@@ -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> |