From 213ddf33614499d9d9183ba8f682c368e6054d87 Mon Sep 17 00:00:00 2001 From: songer Date: Wed, 19 Dec 2018 16:31:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BC=AB=E6=B0=B4=E5=A1=AB=E5=85=85=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=A2=9E=E5=8A=A0=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../opencv/base/BaseMethodController.java | 43 +++++++++++++-- src/main/webapp/view/base/floodfill.jsp | 54 +++++++++++++------ 2 files changed, 76 insertions(+), 21 deletions(-) diff --git a/src/main/java/com/acts/opencv/base/BaseMethodController.java b/src/main/java/com/acts/opencv/base/BaseMethodController.java index eb4d56f..4fdf482 100644 --- a/src/main/java/com/acts/opencv/base/BaseMethodController.java +++ b/src/main/java/com/acts/opencv/base/BaseMethodController.java @@ -366,7 +366,7 @@ public class BaseMethodController extends BaseController { public void floodfill(HttpServletResponse response, String imagefile, double graysize, double lodiff, double updiff, int flag) { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); - logger.info("\n 锐化操作"); + logger.info("\n 漫水填充操作"); String sourcePath = Constants.PATH + imagefile; logger.info("url==============" + sourcePath); @@ -374,12 +374,47 @@ public class BaseMethodController extends BaseController { // Mat mask = new Mat(source.rows() + 2, source.cols() + 2, source.type()); Mat mask = new Mat(); Rect rect = new Rect(); + //简单调用方式 +// Imgproc.floodFill(source, mask, new Point(0, 0), new Scalar(graysize)); + + // 表示floodFill函数标识符低八位的连通值4、8 0-7位可以设置为4或8 + int g_nConnectivity = 4; + // 中间八位部分,新的重新绘制的像素值 255,中8为8-15位,当此值不设置或为0时掩码mask会默认设置为1 + int g_nNewMaskVal = 255; + /** + * 漫水填充的模式:0 默认方式,既不选FLOODFILL_FIXED_RANGE又不选FLOODFILL_MASK_ONLY + * FLOODFILL_FIXED_RANGE:每个像素点都将于种子点,而不是相邻点相比较。即设置此值时, + * 则只有当某个相邻点与种子像素之间的差值在指定范围内才填充,否则考虑当前点与其相邻点的差是否落在制定范围 + * FLOODFILL_MASK_ONLY 如果设置,函数不填充原始图像,而去填充掩码图像。 + */ + int g_nFillMode = 0; + if(flag == 0){//默认方式 + g_nFillMode = 0; + }else if(flag == 1){//FLOODFILL_FIXED_RANGE方式 + g_nFillMode = Imgproc.FLOODFILL_FIXED_RANGE; + }else{//FLOODFILL_MASK_ONLY方式 + g_nFillMode = Imgproc.FLOODFILL_MASK_ONLY; + mask = new Mat(source.rows() + 2, source.cols() + 2, source.type());// 延展图像 + } + + + System.out.println(g_nNewMaskVal << 8); + + int flags = g_nConnectivity | (g_nNewMaskVal << 8) | g_nFillMode; + + + //使用mask调用方式 Imgproc.floodFill(source, mask, new Point(0, 0), new Scalar(graysize), rect, new Scalar(lodiff), new Scalar( - updiff), flag); + updiff), flags); try { - byte[] imgebyte = OpenCVUtil.covertMat2Byte1(source); - renderImage(response, imgebyte); + if(flag==2){//FLOODFILL_MASK_ONLY方式填充的是掩码图像 + byte[] imgebyte = OpenCVUtil.covertMat2Byte1(mask); + renderImage(response, imgebyte); + }else{ + byte[] imgebyte = OpenCVUtil.covertMat2Byte1(source); + renderImage(response, imgebyte); + } } catch (IOException e) { e.printStackTrace(); } diff --git a/src/main/webapp/view/base/floodfill.jsp b/src/main/webapp/view/base/floodfill.jsp index af06b56..30ed119 100644 --- a/src/main/webapp/view/base/floodfill.jsp +++ b/src/main/webapp/view/base/floodfill.jsp @@ -107,16 +107,16 @@

- addweighted + 漫水填充floodfill

参考资料:
- Opencv官方文档:addweighted
-
锐化:dst (I)= saturate ( src1(I)* lodiff + src2(I)* updiff + flag ) - public static void addWeighted(Mat src1, double lodiff, Mat src2, double updiff, double flag, Mat dst); 各参数说明:

+ Opencv官方文档:floodfill
+ OpenCV漫水填充算法
+
public static int floodFill(Mat image, Mat mask, Point seedPoint, Scalar newVal, Rect rect, Scalar loDiff, Scalar upDiff, int flags); 各参数说明: @@ -125,33 +125,53 @@ - - + + - - + + - - + + - - + + - - + + - - + + + + + + + + + + + +
#
1.Mat src1图层1对应的Mat对象Mat image输入/输出1通道或3通道,8位或浮点图像
2.double lodiff图层1的透明度权重Mat mask操作掩模,。它应该为单通道、8位、长和宽上都比输入图像 image 大两个像素点的图像。第二个版本的floodFill需要使用以及更新掩膜,所以这个mask参数我们一定要将其准备好并填在此处。需要注意的是,漫水填充不会填充掩膜mask的非零像素区域。例如,一个边缘检测算子的输出可以用来作为掩膜,以防止填充到边缘。同样的,也可以在多次的函数调用中使用同一个掩膜,以保证填充的区域不会重叠。另外需要注意的是,掩膜mask会比需填充的图像大,所以 mask 中与输入图像(x,y)像素点相对应的点的坐标为(x+1,y+1)。
3.Mat src2图层2对应的Mat对象Point seedPointPoint类型的seedPoint,漫水填充算法的起始点
4.double updiff图层2的透明度权重Scalar newValScalar类型的newVal,像素点被染色的值,即在重绘区域像素的新值
5.double flag一个加到权重总和上的标量值,越大合并图像越明亮Rect rectRect类型的rect,有默认值0,一个可选的参数,用于设置floodFill函数将要重绘区域的最小边界矩形区域。
6.Mat dst目标图像mat Scalar loDiffScalar类型的loDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之负差(lower brightness/color difference)的最大值。
7. Scalar upDiffScalar类型的upDiff,有默认值Scalar( ),表示当前观察像素值与其部件邻域像素值或者待加入该部件的种子像素之间的亮度或颜色之正差(lower brightness/color difference)的最大值。
6.int flagsint类型的flags,操作标志符,此参数包含三个部分,比较复杂
+ 低八位(第0~7位)用于控制算法的连通性,可取4 (4为缺省值) 或者 8。如果设为4,表示填充算法只考虑当前像素水平方向和垂直方向的相邻点;如果设为 8,除上述相邻点外,还会包含对角线方向的相邻点。
+ 高八位部分(16~23位) 可以为0 或者如下两种选项标识符的组合:      +FLOODFILL_FIXED_RANGE - 如果设置为这个标识符的话,就会考虑当前像素与种子像素之间的差,否则就考虑当前像素与其相邻像素的差。也就是说,这个范围是浮动的。 +FLOODFILL_MASK_ONLY - 如果设置为这个标识符的话,函数不会去填充改变原始图像 (也就是忽略第三个参数newVal), 而是去填充掩模图像(mask)。这个标识符只对第二个版本的floodFill有用,因第一个版本里面压根就没有mask参数。
+ 中间八位部分,上面关于高八位FLOODFILL_MASK_ONLY标识符中已经说的很明显,需要输入符合要求的掩码。Floodfill的flags参数的中间八位的值就是用于指定填充掩码图像的值的。但如果flags中间八位的值为0,则掩码会用1来填充。
+ 而所有flags可以用or操作符连接起来,即“|”。例如,如果想用8邻域填充,并填充固定像素值范围,填充掩码而不是填充源图像,以及设填充值为38,那么输入的参数是这样: + flags=8 | FLOODFILL_MASK_ONLY | FLOODFILL_FIXED_RANGE | (38<<8) + + +
@@ -183,7 +203,7 @@ - + 漫水填充 重置