| @@ -211,11 +211,23 @@ | |||
| <artifactId>tess4j</artifactId> | |||
| <version>3.0.0</version> | |||
| </dependency> --> | |||
| <dependency> | |||
| <groupId>net.sourceforge.tess4j</groupId> | |||
| <artifactId>tess4j</artifactId> | |||
| <version>3.0.0</version> | |||
| </dependency> | |||
| <dependency> | |||
| <groupId>net.sourceforge.tess4j</groupId> | |||
| <artifactId>tess4j</artifactId> | |||
| <version>3.0.0</version> | |||
| </dependency> | |||
| <!--zxing二维码识别 --> | |||
| <dependency> | |||
| <groupId>com.google.zxing</groupId> | |||
| <artifactId>core</artifactId> | |||
| <version>3.3.0</version> | |||
| </dependency> | |||
| <!-- com.google.zxing/javase --> | |||
| <dependency> | |||
| <groupId>com.google.zxing</groupId> | |||
| <artifactId>javase</artifactId> | |||
| <version>3.3.0</version> | |||
| </dependency> | |||
| </dependencies> | |||
| @@ -1,7 +1,11 @@ | |||
| package com.acts.opencv.base; | |||
| import java.awt.image.BufferedImage; | |||
| import java.io.IOException; | |||
| import java.util.ArrayList; | |||
| import java.util.HashMap; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.Vector; | |||
| import javax.servlet.http.HttpServletResponse; | |||
| @@ -29,6 +33,14 @@ import com.acts.opencv.common.utils.Constants; | |||
| import com.acts.opencv.common.utils.OpenCVUtil; | |||
| import com.acts.opencv.common.web.BaseController; | |||
| import com.acts.opencv.demo.DemoController; | |||
| import com.google.zxing.Binarizer; | |||
| import com.google.zxing.BinaryBitmap; | |||
| import com.google.zxing.DecodeHintType; | |||
| import com.google.zxing.LuminanceSource; | |||
| import com.google.zxing.MultiFormatReader; | |||
| import com.google.zxing.Result; | |||
| import com.google.zxing.client.j2se.BufferedImageLuminanceSource; | |||
| import com.google.zxing.common.HybridBinarizer; | |||
| @Controller | |||
| @@ -178,6 +190,99 @@ public class BaseMethodController extends BaseController { | |||
| } | |||
| /** | |||
| * 自适用二值化+zxing识别条形码 | |||
| * @Author 王嵩 | |||
| * @param response | |||
| * @param imagefile | |||
| * @param binaryType 二值化类型 | |||
| * @param blockSize 附近区域面积 | |||
| * @param constantC 它只是一个常数,从平均值或加权平均值中减去的常数 | |||
| * @Date 2018年5月17日 | |||
| * 更新日志 | |||
| * 2018年5月17日 王嵩 首次创建 | |||
| */ | |||
| @RequestMapping(value = "zxing") | |||
| public void zxing(HttpServletResponse response, String imagefile, Integer adaptiveMethod, Integer binaryType, | |||
| Integer blockSize, Double constantC) { | |||
| // | |||
| System.loadLibrary(Core.NATIVE_LIBRARY_NAME); | |||
| logger.info("\n 自适用二值化方法"); | |||
| // 灰度化 | |||
| // Imgproc.cvtColor(source, destination, Highgui.CV_LOAD_IMAGE_GRAYSCALE); | |||
| String sourcePath = Constants.PATH + imagefile; | |||
| logger.info("url==============" + sourcePath); | |||
| // 加载为灰度图显示 | |||
| Mat source = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE); | |||
| Mat destination = new Mat(source.rows(), source.cols(), source.type()); | |||
| logger.info("binaryType:{},blockSize:{},constantC:{}", binaryType, blockSize, constantC); | |||
| switch (adaptiveMethod) { | |||
| case 0: | |||
| adaptiveMethod = Imgproc.ADAPTIVE_THRESH_MEAN_C; | |||
| break; | |||
| case 1: | |||
| adaptiveMethod = Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C; | |||
| break; | |||
| } | |||
| switch (binaryType) { | |||
| case 0: | |||
| binaryType = Imgproc.THRESH_BINARY; | |||
| break; | |||
| case 1: | |||
| binaryType = Imgproc.THRESH_BINARY_INV; | |||
| break; | |||
| case 2: | |||
| binaryType = Imgproc.THRESH_TRUNC; | |||
| break; | |||
| case 3: | |||
| binaryType = Imgproc.THRESH_TOZERO; | |||
| break; | |||
| case 4: | |||
| binaryType = Imgproc.THRESH_TOZERO_INV; | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| // Imgproc.adaptiveThreshold(source, destination, 255, adaptiveMethod, binaryType, blockSize, constantC); | |||
| Imgproc.threshold(source, destination, 190, 255, Imgproc.THRESH_BINARY); | |||
| String result = parseCode(destination); | |||
| renderString(response, result); | |||
| } | |||
| private static String parseCode(Mat mat) { | |||
| String resultText = "无法识别!!!"; | |||
| try { | |||
| MultiFormatReader formatReader = new MultiFormatReader(); | |||
| // if (!file.exists()) { | |||
| // System.out.println("nofile"); | |||
| // return; | |||
| // } | |||
| // BufferedImage image = ImageIO.read(file); | |||
| BufferedImage image = OpenCVUtil.toBufferedImage(mat); | |||
| LuminanceSource source = new BufferedImageLuminanceSource(image); | |||
| Binarizer binarizer = new HybridBinarizer(source); | |||
| BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); | |||
| Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>(); | |||
| hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); | |||
| Result result = formatReader.decode(binaryBitmap, hints); | |||
| StringBuffer sbuffer = new StringBuffer(); | |||
| sbuffer.append("解析结果 = " + result.toString() + "\n"); | |||
| sbuffer.append("二维码格式类型 = " + result.getBarcodeFormat() + "\n"); | |||
| sbuffer.append("二维码文本内容 = " + result.getText() + "\n"); | |||
| resultText = sbuffer.toString(); | |||
| } catch (Exception e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return resultText; | |||
| } | |||
| /** | |||
| * 高斯滤波方法测试 | |||
| * 创建者 Songer | |||
| @@ -205,6 +310,44 @@ public class BaseMethodController extends BaseController { | |||
| } | |||
| } | |||
| /** | |||
| * 图像锐化操作 | |||
| * @Author 王嵩 | |||
| * @param response | |||
| * @param imagefile | |||
| * @param ksize 中值滤波内核size | |||
| * @param alpha 控制图层src1的透明度 | |||
| * @param beta 控制图层src2的透明度 | |||
| * @param gamma gamma越大合并的影像越明亮 void | |||
| * @Date 2018年5月18日 | |||
| * 更新日志 | |||
| * 2018年5月18日 王嵩 首次创建 | |||
| * | |||
| */ | |||
| @RequestMapping(value = "sharpness") | |||
| public void sharpness(HttpServletResponse response, String imagefile, int ksize, double alpha, double beta, | |||
| double gamma) { | |||
| System.loadLibrary(Core.NATIVE_LIBRARY_NAME); | |||
| logger.info("\n 锐化操作"); | |||
| String sourcePath = Constants.PATH + imagefile; | |||
| logger.info("url==============" + sourcePath); | |||
| Mat source = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_COLOR); | |||
| Mat destination = new Mat(source.rows(), source.cols(), source.type()); | |||
| // 先进行中值滤波操作 | |||
| Imgproc.medianBlur(source, destination, 2 * ksize + 1); | |||
| // 通过合并图层的方式进行效果增强 alpha控制src1的透明度,beta控制src2 的透明图;gamma越大合并的影像越明亮 | |||
| // public static void addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst) | |||
| Core.addWeighted(source, alpha, destination, beta, 0, destination); | |||
| try { | |||
| byte[] imgebyte = OpenCVUtil.covertMat2Byte1(destination); | |||
| renderImage(response, imgebyte); | |||
| } catch (IOException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| } | |||
| /** | |||
| * 图片缩放方法测试 | |||
| * 创建者 Songer | |||
| @@ -630,6 +773,7 @@ public class BaseMethodController extends BaseController { | |||
| Core.normalize(destination, destination, 0, 255, Core.NORM_MINMAX, -1, new Mat()); | |||
| // minMaxLoc(imagematch, minVal, maxVal2, minLoc, maxLoc01, new Mat()); | |||
| MinMaxLocResult minmaxLoc = Core.minMaxLoc(destination); | |||
| logger.info("相似值=================:最大:" + minmaxLoc.maxVal + " 最小:" + minmaxLoc.minVal); | |||
| Point matchLoc = new Point(); | |||
| switch (method) { | |||
| case 0: | |||
| @@ -695,7 +839,7 @@ public class BaseMethodController extends BaseController { | |||
| logger.info("\n 灰度直方图测试"); | |||
| String sourcePath = Constants.PATH + imagefile; | |||
| Mat source = Highgui.imread(sourcePath, Highgui.CV_LOAD_IMAGE_GRAYSCALE); | |||
| java.util.List<Mat> images = new ArrayList<>(); | |||
| List<Mat> images = new ArrayList<Mat>(); | |||
| images.add(source); | |||
| MatOfInt channels = new MatOfInt(0); // 图像通道数,0表示只有一个通道 | |||
| MatOfInt histSize = new MatOfInt(cols); // CV_8U类型的图片范围是0~255,共有256个灰度级 | |||
| @@ -1,6 +1,5 @@ | |||
| package com.acts.opencv.common.utils; | |||
| import java.awt.Image; | |||
| import java.awt.image.BufferedImage; | |||
| import java.awt.image.DataBufferByte; | |||
| import java.io.IOException; | |||
| @@ -19,7 +18,7 @@ public class OpenCVUtil { | |||
| public static BufferedImage covertMat2Buffer(Mat mat) throws IOException { | |||
| long time1 = new Date().getTime(); | |||
| // Mat 转byte数组 | |||
| BufferedImage originalB = (BufferedImage) toBufferedImage(mat); | |||
| BufferedImage originalB = toBufferedImage(mat); | |||
| long time3 = new Date().getTime(); | |||
| System.out.println("保存读取方法2转=" + (time3 - time1)); | |||
| return originalB; | |||
| @@ -48,7 +47,7 @@ public class OpenCVUtil { | |||
| return mob.toArray(); | |||
| } | |||
| public static Image toBufferedImage(Mat m) { | |||
| public static BufferedImage toBufferedImage(Mat m) { | |||
| int type = BufferedImage.TYPE_BYTE_GRAY; | |||
| if (m.channels() > 1) { | |||
| type = BufferedImage.TYPE_3BYTE_BGR; | |||
| @@ -1,7 +1,7 @@ | |||
| driverClassName = com.mysql.jdbc.Driver | |||
| #url=jdbc:mysql://192.168.1.61:3306/acts_java_opencv?characterEncoding=UTF-8&useSSL=false | |||
| #username = root | |||
| #password = root | |||
| url=jdbc:mysql://192.168.1.61:3306/acts_java_opencv?characterEncoding=UTF-8&useSSL=false | |||
| username = root | |||
| password = root | |||
| initialSize = 10 | |||
| maxActive = 15 | |||
| minIdle = 3 | |||
| @@ -127,7 +127,9 @@ desired effect | |||
| <ul class="treeview-menu"> | |||
| <li><a href="#view/base/binary.jsp"><i class="fa fa-circle-o"></i>二值化</a></li> | |||
| <li><a href="#view/base/adaptiveBinary.jsp"><i class="fa fa-circle-o"></i>自适用二值化</a></li> | |||
| <li><a href="#view/base/zxing.jsp"><i class="fa fa-circle-o"></i>zxing识别二维码</a></li> | |||
| <li><a href="#view/base/gaussian.jsp"><i class="fa fa-circle-o"></i> 模糊</a></li> | |||
| <li><a href="#view/base/sharpness.jsp"><i class="fa fa-circle-o"></i> 图像锐化</a></li> | |||
| <li><a href="#view/base/resize.jsp"><i class="fa fa-circle-o"></i> 缩放</a></li> | |||
| <li><a href="#view/base/erosion_dilation.jsp"><i class="fa fa-circle-o"></i>腐蚀膨胀</a></li> | |||
| <li><a href="#view/base/morphologyEx.jsp"><i class="fa fa-circle-o"></i>腐蚀膨胀进阶</a></li> | |||
| @@ -0,0 +1,227 @@ | |||
| <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> | |||
| <%@include file="/module/include/common.jsp"%> | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <sys:header title="首页" extLibs=""></sys:header> | |||
| <link rel="stylesheet" href="${ctxStatic}/plugins/bootstrap-slider/slider.css"> | |||
| <script type="text/javascript"> | |||
| $(function(){ | |||
| var baseImageFile = "/statics/sourceimage/ticket1.png" | |||
| var newImagePath = "/statics/distimage/lena.png" | |||
| $("#oldimg").attr("src",baseUrl+baseImageFile); | |||
| //$("#newimg").attr("src",baseUrl+baseImageFile); | |||
| //锐化 | |||
| $("#sharpness").click(function(){ | |||
| var ksize = $("#ksize").val(); | |||
| var alpha = $("#alpha").val(); | |||
| var beta = $("#beta").val(); | |||
| var gamma = $("#gamma").val(); | |||
| //alert(ksize+"|"+alpha+"|"+beta+"|"+gamma); | |||
| var imagefile = baseImageFile; | |||
| var srcurl = ctxPath+"/base/sharpness?_" + $.now()+"&ksize="+ksize+"&alpha="+alpha+"&beta="+beta+"&gamma="+gamma+"&imagefile="+baseImageFile; | |||
| $("#newimg").attr("src",srcurl); | |||
| }); | |||
| //重置 | |||
| $("#reset").click(function(){ | |||
| var baseImageFile = "/statics/sourceimage/lena.png"; | |||
| $("#oldimg").attr("src",baseUrl+baseImageFile); | |||
| $("#newimg").attr("src",''); | |||
| layer.msg('重置成功!', {icon: 1}); | |||
| }); | |||
| //滑动插件加载 | |||
| $("#ksize").slider({ | |||
| tooltip: 'always', | |||
| }); | |||
| $("#alpha").slider({ | |||
| tooltip: 'always', | |||
| }); | |||
| $("#beta").slider({ | |||
| tooltip: 'always', | |||
| }); | |||
| $("#gamma").slider({ | |||
| tooltip: 'always', | |||
| }); | |||
| $("#ksize").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#ksize").val(e.value.newValue); | |||
| $("#sharpness").click(); | |||
| }); | |||
| $("#alpha").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#alpha").val(e.value.newValue); | |||
| $("#sharpness").click(); | |||
| }); | |||
| $("#beta").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#beta").val(e.value.newValue); | |||
| $("#sharpness").click(); | |||
| }); | |||
| $("#gamma").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#gamma").val(e.value.newValue); | |||
| $("#sharpness").click(); | |||
| }); | |||
| }); | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div class="box-group" id="accordion"> | |||
| <!-- we are adding the .panel class so bootstrap.js collapse plugin detects it --> | |||
| <div class="panel box box-primary"> | |||
| <div class="box-header with-border"> | |||
| <h4 class="box-title"> | |||
| <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"> | |||
| addweighted | |||
| </a> | |||
| </h4> | |||
| </div> | |||
| <div id="collapseOne" class="panel-collapse collapse"><!--class="panel-collapse collapse in"中的 in 控制展开 --> | |||
| <div class="box-body"> | |||
| <h4>参考资料:<br> | |||
| <a href="https://docs.opencv.org/2.4.13.6/modules/core/doc/operations_on_arrays.html#addweighted">Opencv官方文档:addweighted</a> <br> | |||
| <br>锐化:dst (I)= saturate ( src1(I)* alpha + src2(I)* beta + gamma ) | |||
| public static void addWeighted(Mat src1, double alpha, Mat src2, double beta, double gamma, Mat dst); 各参数说明:</h4> | |||
| <table class="table table-bordered"> | |||
| <tbody><tr> | |||
| <th style="width: 10px">#</th> | |||
| <th style="width: 20%">参数</th> | |||
| <th>说明</th> | |||
| </tr> | |||
| <tr> | |||
| <td>1.</td> | |||
| <td>Mat src1</td> | |||
| <td>图层1对应的Mat对象</td> | |||
| </tr> | |||
| <tr> | |||
| <td>2.</td> | |||
| <td>double alpha</td> | |||
| <td>图层1的透明度权重</td> | |||
| </tr> | |||
| <tr> | |||
| <td>3.</td> | |||
| <td>Mat src2</td> | |||
| <td>图层2对应的Mat对象</td> | |||
| </tr> | |||
| <tr> | |||
| <td>4.</td> | |||
| <td>double beta</td> | |||
| <td>图层2的透明度权重</td> | |||
| </tr> | |||
| <tr> | |||
| <td>5.</td> | |||
| <td>double gamma</td> | |||
| <td>一个加到权重总和上的标量值,越大合并图像越明亮</td> | |||
| </tr> | |||
| <tr> | |||
| <td>6.</td> | |||
| <td>Mat dst</td> | |||
| <td>目标图像mat</td> | |||
| </tr> | |||
| </tbody></table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- /.box-body --> | |||
| <h4> 高斯滤波测试</h4> | |||
| <div class="box-body"> | |||
| <table class="table table-bordered"> | |||
| <tbody><tr> | |||
| <th style="width:20%">中值滤波ksize 内核大小=2*ksize+1</th> | |||
| <th style="width:20%">alpha图层1的透明度</th> | |||
| <th style="width:20%">beta图层2的透明度</th> | |||
| <th style="width:20%">gamma合并图像亮度</th> | |||
| <th style="width: 200px">操作</th> | |||
| </tr> | |||
| <tr> | |||
| <td> | |||
| <input id="ksize" data-slider-id='ex1Slider' type="text" data-slider-min="0" data-slider-max="10" data-slider-step="1" data-slider-value="3"/> | |||
| </td> | |||
| <td> | |||
| <input id="alpha" data-slider-id='ex1Slider' type="text" data-slider-min="0" data-slider-max="4" data-slider-step="0.1" data-slider-value="2.1"/> | |||
| </td> | |||
| <td> | |||
| <input id="beta" data-slider-id='ex1Slider' type="text" data-slider-min="-2" data-slider-max="2" data-slider-step="0.1" data-slider-value="-1.1"/> | |||
| </td> | |||
| <td> | |||
| <input id="gamma" data-slider-id='ex1Slider' type="text" data-slider-min="0" data-slider-max="100" data-slider-step="1" data-slider-value="0"/> | |||
| </td> | |||
| <td><a class="btn btn-info" id="sharpness"><i class="fa fa-object-ungroup"></i>锐化</a> | |||
| <a class="btn btn-info" id="reset"><i class="fa fa-refresh"></i>重置</a></td> | |||
| </tr> | |||
| </tbody></table></div> | |||
| <div class="row"> | |||
| <div class="col-sm-6"> | |||
| <div class="box box-primary"> | |||
| <div class="box-header with-border"> | |||
| <h3 class="box-title">原图</h3> | |||
| <span class="label label-primary pull-right"><i class="fa fa-html5"></i></span> | |||
| </div><!-- /.box-header --> | |||
| <div class="box-body"> | |||
| <p>未识别前的原文件。</p> | |||
| <img id="oldimg" src="" alt="原图" /> | |||
| </div><!-- /.box-body --> | |||
| </div><!-- /.box --> | |||
| </div><!-- /.col --> | |||
| <div class="col-sm-6"> | |||
| <div class="box box-danger"> | |||
| <div class="box-header with-border"> | |||
| <h3 class="box-title">识别后的图片</h3> | |||
| <span class="label label-danger pull-right"><i class="fa fa-database"></i></span> | |||
| </div><!-- /.box-header --> | |||
| <div class="box-body"> | |||
| <p>点击识别按钮后,将显示识别后的文件。</p> | |||
| <img id="newimg" src="" alt="识别后的图" /> | |||
| </div><!-- /.box-body --> | |||
| </div><!-- /.box --> | |||
| </div><!-- /.col --> | |||
| </div> | |||
| </body> | |||
| <script src="${ctxStatic}/plugins/bootstrap-slider/bootstrap-slider.js?t=${version}"></script> | |||
| </html> | |||
| @@ -0,0 +1,265 @@ | |||
| <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> | |||
| <%@include file="/module/include/common.jsp"%> | |||
| <!DOCTYPE html> | |||
| <html> | |||
| <head> | |||
| <sys:header title="首页" extLibs=""></sys:header> | |||
| <link rel="stylesheet" href="${ctxStatic}/plugins/iCheck/all.css?t=${version}"> | |||
| <link rel="stylesheet" href="${ctxStatic}/plugins/bootstrap-slider/slider.css"> | |||
| <link rel="stylesheet" href="${ctxStatic}/plugins/iCheck/minimal/blue.css?t=${version}"> | |||
| <script type="text/javascript"> | |||
| $(function(){ | |||
| var baseImageFile = "/statics/sourceimage/ticket.png" | |||
| var newImagePath = "/statics/distimage/lena.png" | |||
| $("#oldimg").attr("src",baseUrl+baseImageFile); | |||
| //$("#newimg").attr("src",baseUrl+baseImageFile); | |||
| $("#binary").click(function(){ | |||
| var binaryType = $("input[name='thresh_type']:checked").val(); | |||
| var adaptiveMethod = $("input[name='adaptiveMethod']:checked").val(); | |||
| var blockSize = $("#block_value").val(); | |||
| var constantC = $("#constantC").val(); | |||
| var imagefile = baseImageFile; | |||
| $.SaveForm({ | |||
| url : ctxPath+"/base/zxing?_" + $.now(), | |||
| param: {"binaryType":binaryType,"blockSize":blockSize,"adaptiveMethod":adaptiveMethod,"constantC":constantC,"imagefile":baseImageFile}, | |||
| json:true, | |||
| success : function(result) { | |||
| $("#zxingResult").html(result); | |||
| layer.msg('操作成功!', {icon: 1}); | |||
| } | |||
| }); | |||
| }); | |||
| //重置 | |||
| $("#reset").click(function(){ | |||
| var baseImageFile = "/statics/sourceimage/ticket.jpg"; | |||
| $("#oldimg").attr("src",baseUrl+baseImageFile); | |||
| $("#newimg").attr("src",''); | |||
| layer.msg('重置成功!', {icon: 1}); | |||
| }); | |||
| //滑动插件加载 | |||
| $("#block_value,#constantC").slider({ | |||
| tooltip: 'always', | |||
| }); | |||
| $("#constantC").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#constantC").val(e.value.newValue) | |||
| $("#binary").click(); | |||
| }); | |||
| $("#block_value").on("slide", function(slideEvt) { | |||
| console.log(slideEvt.value); | |||
| //$("#binary").click(); | |||
| }).on("change", function (e) { | |||
| //当值发生改变的时候触发 | |||
| //console.info(e); | |||
| //获取旧值和新值 | |||
| console.info(e.value.oldValue + '--' + e.value.newValue); | |||
| $("#block_value").val(e.value.newValue) | |||
| $("#binary").click(); | |||
| }); | |||
| //iCheck样式加载 | |||
| $("input[name='thresh_type'],input[name='adaptiveMethod']").iCheck({ | |||
| checkboxClass: 'icheckbox_flat', | |||
| radioClass: 'iradio_flat' | |||
| }); | |||
| //type类型更换时自动生成 | |||
| $("input[name='thresh_type'],input[name='adaptiveMethod']").on('ifChecked', function(event){ | |||
| $("#binary").click(); | |||
| //alert($(event).text()); | |||
| }); | |||
| }); | |||
| </script> | |||
| </head> | |||
| <body> | |||
| <div class="box-body"> | |||
| <div class="box-group" id="accordion"> | |||
| <!-- we are adding the .panel class so bootstrap.js collapse plugin detects it --> | |||
| <div class="panel box box-primary"> | |||
| <div class="box-header with-border"> | |||
| <h4 class="box-title"> | |||
| <a data-toggle="collapse" data-parent="#accordion" href="#collapseOne"> | |||
| 1.adaptivethreshold函数介绍 | |||
| </a> | |||
| </h4> | |||
| </div> | |||
| <div id="collapseOne" class="panel-collapse collapse"><!--class="panel-collapse collapse in"中的 in 控制展开 --> | |||
| <div class="box-body"> | |||
| <h4>参考资料:<br> | |||
| <a href="https://docs.opencv.org/2.4.13.6/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold">https://docs.opencv.org/2.4.13.6/modules/imgproc/doc/miscellaneous_transformations.html#adaptivethreshold</a> <br> | |||
| <br> | |||
| public static void adaptiveThreshold(Mat src, Mat dst, double maxValue, int adaptiveMethod, int thresholdType, int blockSize, double C); 各参数说明: | |||
| adaptiveThreshold()支持两种自适应方法,即ADAPTIVE_THRESH_MEAN_C(平均)和ADAPTIVE_THRESH_GAUSSIAN_C(高斯)。 | |||
| 在两种情况下,自适应阈值T(x, y)。通过计算每个像素周围bxb大小像素块的加权均值并减去常量C得到。其中, | |||
| b由blockSize给出,大小必须为奇数;如果使用平均的方法,则所有像素周围的权值相同; | |||
| 如果使用高斯的方法,则(x,y)周围的像素的权值则根据其到中心点的距离通过高斯方程得到。 | |||
| </h4> | |||
| <table class="table table-bordered"> | |||
| <tbody><tr> | |||
| <th style="width: 10px">#</th> | |||
| <th style="width: 20%">参数</th> | |||
| <th>说明</th> | |||
| </tr> | |||
| <tr> | |||
| <td>1.</td> | |||
| <td>Mat src</td> | |||
| <td>源文件Mat对象,单通道, 8-bit or 32-bit</td> | |||
| </tr> | |||
| <tr> | |||
| <td>2.</td> | |||
| <td>Mat dst</td> | |||
| <td>目标文件Mat对象,将和源图片有着相同的大小和类型</td> | |||
| </tr> | |||
| <tr> | |||
| <td>3.</td> | |||
| <td>double maxValue</td> | |||
| <td>最大像素值</td> | |||
| </tr> | |||
| <tr> | |||
| <td>4.</td> | |||
| <td>int adaptiveMethod</td> | |||
| <td>自适应方法,平均或高斯</td> | |||
| </tr> | |||
| <tr> | |||
| <td>5.</td> | |||
| <td>int thresholdType</td> | |||
| <td>二值化类型</td> | |||
| </tr> | |||
| <tr> | |||
| <td>6.</td> | |||
| <td>int blockSize</td> | |||
| <td>范围对比块大小</td> | |||
| </tr> | |||
| <tr> | |||
| <td>7.</td> | |||
| <td>double C</td> | |||
| <td>常量</td> | |||
| </tr> | |||
| </tbody></table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <div class="panel box box-success"> | |||
| <div class="box-header with-border"> | |||
| <h4 class="box-title"> | |||
| <a data-toggle="collapse" data-parent="#accordion" href="#collapseTwo"> | |||
| 2.二值化类型说明 | |||
| </a> | |||
| </h4> | |||
| </div> | |||
| <div id="collapseTwo" class="panel-collapse collapse"> | |||
| <div class="box-body"> | |||
| <table class="table table-bordered"> | |||
| <tbody><tr> | |||
| <th style="width: 10px">#</th> | |||
| <th style="width: 10%">二值化类型</th> | |||
| <th>公式</th> | |||
| <th>效果图</th> | |||
| <th>解释说明</th> | |||
| </tr> | |||
| <tr> | |||
| <td>1.</td> | |||
| <td>THRESH_BINARY</td> | |||
| <td><img alt="" src ="${ctxStatic}/images/THRESH_BINARY_1.png"></td> | |||
| <td><img alt="" src="${ctxStatic}/images/THRESH_BINARY_2.png"></td> | |||
| <td>在运用该阈值类型的时候,先要选定一个特定的阈值量,比如:125,这样,新的阈值产生规则可以解释为大于125的像素点的灰度值设定为最大值(如8位灰度值最大为255),灰度值小于125的像素点的灰度值设定为0。</td> | |||
| </tr> | |||
| <tr> | |||
| <td>2.</td> | |||
| <td>THRESH_BINARY_INV</td> | |||
| <td><img alt="" src ="${ctxStatic}/images/THRESH_BINARY_INV_1.png"></td> | |||
| <td><img alt="" src="${ctxStatic}/images/THRESH_BINARY_INV_2.png"></td> | |||
| <td>该阈值化与二进制阈值化相似,先选定一个特定的灰度值作为阈值,不过最后的设定值相反。(在8位灰度图中,例如大于阈值的设定为0,而小于该阈值的设定为255)。</td> | |||
| </tr> | |||
| </tbody> | |||
| </table> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| </div> | |||
| <!-- /.box-body --> | |||
| <h4> | |||
| 二值化效果测试 </h4> | |||
| <div class="box-body"> | |||
| <table class="table table-bordered"> | |||
| <tbody><tr> | |||
| <th style="width:15%">blockSize</th> | |||
| <th style="width:15%">constantC</th> | |||
| <th style="width:30%">type</th> | |||
| <th style="width:20%">adaptiveMethod</th> | |||
| <th style="width: 200px">操作</th> | |||
| </tr> | |||
| <tr> | |||
| <td> | |||
| <input id="block_value" data-slider-id='ex1Slider' type="text" data-slider-min="1" data-slider-max="51" data-slider-step="2" data-slider-value="31"/> | |||
| </td> | |||
| <td> | |||
| <input id="constantC" data-slider-id='ex1Slider' type="text" data-slider-min="1" data-slider-max="50" data-slider-step="1" data-slider-value="15"/> | |||
| </td> | |||
| <td> | |||
| <input type="radio" name="thresh_type" value="0" checked="checked"/>THRESH_BINARY | |||
| <input type="radio" name="thresh_type" value="1"/>THRESH_BINARY_INV | |||
| </td> | |||
| <td> | |||
| <input type="radio" name="adaptiveMethod" value="0" checked="checked"/>ADAPTIVE_THRESH_MEAN_C <br> | |||
| <input type="radio" name="adaptiveMethod" value="1"/>ADAPTIVE_THRESH_GAUSSIAN_C | |||
| </td> | |||
| <td><a class="btn btn-info" id="binary"><i class="fa fa-object-ungroup"></i>识别</a> | |||
| <a class="btn btn-info" id="reset"><i class="fa fa-refresh"></i>重置</a></td> | |||
| </tr> | |||
| </tbody></table></div> | |||
| <div class="row"> | |||
| <div class="col-sm-6"> | |||
| <div class="box box-primary"> | |||
| <div class="box-header with-border"> | |||
| <h3 class="box-title">原图</h3> | |||
| <span class="label label-primary pull-right"><i class="fa fa-html5"></i></span> | |||
| </div><!-- /.box-header --> | |||
| <div class="box-body"> | |||
| <p>未识别前的原文件。</p> | |||
| <img id="oldimg" src="" alt="原图" /> | |||
| </div><!-- /.box-body --> | |||
| </div><!-- /.box --> | |||
| </div><!-- /.col --> | |||
| <div class="col-sm-6"> | |||
| <div class="box box-danger"> | |||
| <div class="box-header with-border"> | |||
| <h3 class="box-title">识别后的图片</h3> | |||
| <span class="label label-danger pull-right"><i class="fa fa-database"></i></span> | |||
| </div><!-- /.box-header --> | |||
| <div class="box-body"> | |||
| <p>点击识别按钮后,将显示识别后的文件。</p> | |||
| <div id="zxingResult"></div> | |||
| </div><!-- /.box-body --> | |||
| </div><!-- /.box --> | |||
| </div><!-- /.col --> | |||
| </div> | |||
| </body> | |||
| <script src="${ctxStatic}/plugins/bootstrap-slider/bootstrap-slider.js?t=${version}"></script> | |||
| <script src="${ctxStatic}/plugins/iCheck/icheck.js?t=${version}"></script> | |||
| </html> | |||