创建图片

    Mat mat=new Mat();
mat.create(new Size(516,516),CvType.CV_8UC3);
Imgproc.putText(mat, "hello I'm wdg!", new
Point(50,mat.cols()/2),Imgproc.FONT_HERSHEY_PLAIN,4, new Scalar(255,255,255),2);

创建出来的结果如下:

OPenCv  java 形态学操作(12)_java

形态学操作函数

Imgproc.morphologyEx(src, dst, op, kernel);

  • src:输入图像
  • dst:输出图像
  • op:模式
  • kernel:卷积核(和上一篇一样的获取方法)

这里的模式(op)有以下几种:

  • MORPH_ERODE = 0:腐蚀
  • MORPH_DILATE = 1:膨胀
  • MORPH_OPEN = 2:开操作
  • MORPH_CLOSE = 3:闭操作
  • MORPH_GRADIENT = 4:基本梯度
  • MORPH_TOPHAT = 5:顶帽
  • MORPH_BLACKHAT = 6:黑帽

膨胀和腐蚀

这个我们好理解,我们对上面创建的图片进行膨胀和腐蚀

    Mat mat=new Mat();
mat.create(new Size(516,516),CvType.CV_8UC3);
Imgproc.putText(mat, "hello I'm wdg!", new Point(50,mat.cols()/2),Imgproc.FONT_HERSHEY_PLAIN,4, new Scalar(255,255,255),2);

Mat dst=new Mat();
Mat dilate=new Mat();
Mat kernel=Imgproc.getStructuringElement(Imgproc.CV_SHAPE_CROSS, new Size(3,3));
Imgproc.morphologyEx(mat, dst, Imgproc.MORPH_ERODE, kernel);
Imgproc.morphologyEx(mat, dilate, Imgproc.MORPH_DILATE, kernel);

HighGui.imshow("原图", mat);
HighGui.imshow("原图腐蚀", dst);
HighGui.imshow("原图膨胀", dilate);

HighGui.waitKey(0);

效果:

OPenCv  java 形态学操作(12)_形态操作_02

显然可以看到 的是在膨胀之后整个字体都变粗了,但是在腐蚀之后整个字体变的很细

我们来看看元素是怎样变化的:

OPenCv  java 形态学操作(12)_形态操作_03

通过矩阵元素的变化,我们可以看到元素255的数据的多少,来判断线条的粗细

开操作和闭操作

  Mat mat = new Mat();
mat.create(new Size(516, 516), CvType.CV_8UC3);
Imgproc.putText(mat, "hello I'm wdg!", new Point(50, mat.cols() / 2), Imgproc.FONT_HERSHEY_PLAIN, 16,new Scalar(255, 255, 255), 2);

double d[]=new double[3];
d[0]=255;
d[1]=125;
d[2]=86;

mat.put(150, 260,d);
mat.put(150, 261,d);
mat.put(150, 262,d);

Mat dst = new Mat();
Mat dilate = new Mat();
Mat kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_CROSS, new Size(3, 3));
Imgproc.morphologyEx(mat, dst, Imgproc.MORPH_CLOSE, kernel);
Imgproc.morphologyEx(mat, dilate, Imgproc.MORPH_OPEN, kernel);

File file = new File("D:\\360MoveData\\Users\\lxn\\Desktop\\opencvtest");

if (!file.exists()) {
file.mkdir();
}
String filename1 = "1.txt";

File file1 = new File(file.getAbsoluteFile() + "//" + filename1);
if (!file1.exists()) {
file1.createNewFile();
}

FileWriter fw = new FileWriter(file1);

fw.write("核:");
fw.write("\n");
fw.write(kernel.dump());

fw.write("原图:");
fw.write("\n");

fw.write(mat.submat(145, 160, 258, 300).dump());

fw.write("腐蚀:");
fw.write("\n");

fw.write(dst.submat(145, 160, 258, 300).dump());

fw.write("膨胀");
fw.write("\n");

fw.write(dilate.submat(145, 160, 258, 300).dump());

fw.close();

HighGui.imshow("原图", mat);
HighGui.imshow("原图闭操作", dst);
HighGui.imshow("原图开操作", dilate);

HighGui.waitKey(0);

我们在程序中伪造一些噪点,看开操作和闭合操作对噪点的影响

OPenCv  java 形态学操作(12)_黑帽_04

在原图中的噪点,开操作之后噪点看不到了

OPenCv  java 形态学操作(12)_opencv_05

从数据元素上看,开操作将噪点直接去除了,但是我们看出来闭操作原图有什么影响

OPenCv  java 形态学操作(12)_scala_06

看来还是明显的,如果内核设置为7x7

OPenCv  java 形态学操作(12)_形态操作_07

我是datouniao这几个字体根本就没有了

从元素上变化是这样的:

OPenCv  java 形态学操作(12)_opencv_08

上面的红线有什么样的变化,在闭操作前后,整个图像更加的紧凑了,也就是临近大小的元素更加的紧凑

获取这样还不够明显

我们这样来看

OPenCv  java 形态学操作(12)_java_09

黑色的线条就像是红色方框上的嘴巴,直接闭合了,剩下红色的方框

黑帽和顶帽

    Mat kernel = Imgproc.getStructuringElement(Imgproc.CV_SHAPE_CROSS, new Size(3, 3));

Imgproc.morphologyEx(src, dst2, Imgproc.MORPH_BLACKHAT, kernel);

Imgproc.morphologyEx(src, dst, Imgproc.MORPH_TOPHAT, kernel);

OPenCv  java 形态学操作(12)_scala_10

除了黑帽和顶帽的操作之外,还有其他的梯度操作和焊接操作

            MORPH_ERODE = 0,
            MORPH_DILATE = 1,
            MORPH_OPEN = 2,
            MORPH_CLOSE = 3,
            MORPH_GRADIENT = 4,
            MORPH_TOPHAT = 5,
            MORPH_BLACKHAT = 6,
            MORPH_HITMISS = 7;

梯度操作和焊接操作

我们来看其中形态的变化

OPenCv  java 形态学操作(12)_黑帽_11

换一张图:

OPenCv  java 形态学操作(12)_黑帽_12

感觉梯度操作让整个图像更加的线条明显

上面就是我们对图像形态的一种操作,希望对你有所帮助