中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

怎么才能建立網站運營培訓班有用嗎

怎么才能建立網站,運營培訓班有用嗎,網站 做英文 翻譯 規(guī)則,宜昌小程序開發(fā)公司圖像形態(tài)學 一、像素的距離二、像素的鄰域三、膨脹與腐蝕3.1、結構元素3.2、腐蝕3.3、膨脹 四、形態(tài)學操作4.1、開運算和閉運算4.2、頂帽和黑帽4.3、形態(tài)學梯度4.4、擊中擊不中 一、像素的距離 圖像中像素之間的距離有多種度量方式,其中常用的有歐式距離、棋盤距離…

圖像形態(tài)學

  • 一、像素的距離
  • 二、像素的鄰域
  • 三、膨脹與腐蝕
    • 3.1、結構元素
    • 3.2、腐蝕
    • 3.3、膨脹
  • 四、形態(tài)學操作
    • 4.1、開運算和閉運算
    • 4.2、頂帽和黑帽
    • 4.3、形態(tài)學梯度
    • 4.4、擊中擊不中

一、像素的距離

圖像中像素之間的距離有多種度量方式,其中常用的有歐式距離、棋盤距離和街區(qū)距離。

1. 歐式距離:
歐式距離是指連接兩個點的直線距離。歐式距離用數學公式可以表達如下:

//勾股定理計算
d^2 = (x1-x2)^2+(y1-y2)^2

2. 棋盤距離:

棋盤距離也叫切比雪夫距離,棋盤距離可以用國際象棋中王的走法來說明,也就是王從一個位置走到另一個位置最少需要多少步。

例如,王從b3走到g6最少需要幾步?即b3->c4->d5->e6->f6->g6,共5步。不難發(fā)現,起始位置和終止位置在棋盤上的距離是,橫向5格,縱向3格,所以棋盤距離實際上是橫向距離與縱向距離之間的較大者,用數學公式表達如下:

//兩個向量在任意坐標維度上的最大差值
d = max(|x1-x2|, |y1-y2|)

3. 街區(qū)距離:
街區(qū)距離也稱為曼哈度距離。與棋盤距離不同,在街區(qū)距離中只允許橫向或縱向移動,不允許斜向移動。那么,上例中王的兩個位置即為8步。用數據公式表達如下:

d = |x1-x2| + |y1-y2|
//計算一張圖像中非零像素到最近的零像素的距離,即到零像素的最短距離
void Imgproc.distanceTransform(Mat src, Mat dst, int dstanceType, int maskSize)
  • src:輸入圖像,必須為8位單通道
  • dst:含計算距離的輸出圖像,圖像深度為CV_8U或CV_32F的單通道圖像,尺寸與輸入圖像相同。
  • distanceType:距離類型,可選參數如下:
    • Imgproc.DIST_USER:用戶自定義距離
    • Imgproc.DIST_L1:街區(qū)距離
    • Imgproc.DIST_L2:歐式距離
    • Imgproc.DIST_C:棋盤距離
    • Imgproc.DIST_L12:d=2(sqrt(1+x*x/2)-1)
    • Imgproc.DIST_FAIR:d=c^2(|x|/c-log(1+|x|/c)),其中c=1.3998
    • Imgproc.DIST_WELSCH:d=c^2/2(1-exp(-(x/c)^2)),其中c=2.9846
    • Imgproc.DIST_HUBER:d=|x|<c ? x^2/2 : c(|x|-c/2),其中c=1.345
  • maskSize:距離變化掩碼矩陣尺寸,可選參數如下
    • Imgproc.DIST_MASK_3:數字值=3
    • Imgproc.DIST_MASK_5:數字值=5
    • Imgproc.DIST_MASK_PRECISE

為了使用加速算法,掩碼矩陣必須是對稱的。在計算歐氏距離時,掩碼矩陣為3時只是粗略計算像素距離(水平和垂直方向的變化量為1,對角線方向的變化量為1.4)。

public class DistanceTransform {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//構建一個5*5的小矩陣并導入數據Mat src = new Mat(5, 5, CvType.CV_8UC1);byte[] data = new byte[] {1, 1, 1, 1, 1,1, 1, 1, 1, 1,1, 1, 0, 1, 1,1, 1, 1, 1, 1,1, 1,1 ,1 , 1};src.put(0, 0, data);//打印矩陣數據System.out.println("輸入矩陣:");System.out.println(src.dump());System.out.println();//計算棋盤距離并輸出Mat dst = new Mat();Imgproc.distanceTransform(src, dst, Imgproc.DIST_C, 3);System.out.println("棋盤距離:");System.out.println(dst.dump());System.out.println();//計算街區(qū)距離并輸出Imgproc.distanceTransform(src, dst, Imgproc.DIST_L1, 3);System.out.println("街區(qū)距離:");System.out.println(dst.dump());System.out.println();//計算歐氏距離并輸出Imgproc.distanceTransform(src, dst, Imgproc.DIST_L2, 3);System.out.println("歐氏距離:");System.out.println(dst.dump());System.out.println();}
}
輸入矩陣:
[  1,   1,   1,   1,   1;1,   1,   1,   1,   1;1,   1,   0,   1,   1;1,   1,   1,   1,   1;1,   1,   1,   1,   1]棋盤距離:
[2, 2, 2, 2, 2;2, 1, 1, 1, 2;2, 1, 0, 1, 2;2, 1, 1, 1, 2;2, 2, 2, 2, 2]街區(qū)距離:
[4, 3, 2, 3, 4;3, 2, 1, 2, 3;2, 1, 0, 1, 2;3, 2, 1, 2, 3;4, 3, 2, 3, 4]歐氏距離:
[2.7385864, 2.324295, 1.9100037, 2.324295, 2.7385864;2.324295, 1.3692932, 0.95500183, 1.3692932, 2.324295;1.9100037, 0.95500183, 0, 0.95500183, 1.9100037;2.324295, 1.3692932, 0.95500183, 1.3692932, 2.324295;2.7385864, 2.324295, 1.9100037, 2.324295, 2.7385864]

上面的程序僅用于說明像素距離的計算方法。利用計算出的距離可以實現很多功能。下面示例說明如何用像素距離實現輪廓的細化:

public class Thinning {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像為灰度圖Mat image = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/wang.png");Mat gray = new Mat();Imgproc.cvtColor(image, gray, Imgproc.COLOR_BGR2GRAY);//將灰度圖反相并顯示Core.bitwise_not(gray, gray);HighGui.imshow("gray", gray);HighGui.waitKey(0);//進行高斯濾波和二值化處理Imgproc.GaussianBlur(gray, gray, new Size(5, 5), 2);Imgproc.threshold(gray, gray, 20, 255, Imgproc.THRESH_BINARY);HighGui.imshow("Binary", gray);HighGui.waitKey(0);//計算街區(qū)距離Mat thin = new Mat(gray.size(), CvType.CV_32FC1);Imgproc.distanceTransform(gray, thin, Imgproc.DIST_L1, 3);//獲取最大的街區(qū)距離float max = 0;for (int i = 0; i < thin.rows(); i++) {for (int j = 0; j < thin.cols(); j++) {float[] f = new float[3];thin.get(i, j, f);if (f[0] > max) {max = f[0];}}}//定義用于顯示結果的矩陣,背景為全黑Mat show = Mat.zeros(gray.size(), CvType.CV_8UC1);//將距離符合一定條件的像素設為白色for (int i = 0; i < thin.rows(); i++) {for (int j = 0; j < thin.cols(); j++) {float[] f = new float[3];thin.get(i, j, f);if (f[0] > max / 3) {show.put(i, j, 255);}}}//在屏幕上顯示最后結果HighGui.imshow("thin", show);HighGui.waitKey(0);System.exit(0);}
}

原圖灰度圖反相:
在這里插入圖片描述

二值化:
在這里插入圖片描述

通過計算街區(qū)距離,細化為原來的1/3:
在這里插入圖片描述

二、像素的鄰域

像素的鄰域是指與某一像素相鄰的像素集合。鄰域通常分為4鄰域、8鄰域和D鄰域,如下圖:

//4鄰域,當前像素為中心,上、下、左、右4個像素11 P 11//8鄰域,當前像素為中心,上、下、左、右、左上、左下、右上、右下8個像素
1 1 1
1 P 1
1 1 1//D鄰域,當前像素為中心,左上、左下、右上、右下4個像素
1   1P
1   1	

8鄰域=4鄰域+D鄰域,OpenCV中有如下函數標記圖像中的連通域:

int Imgproc.connectedComponents(Mat image, Mat labels, int connectivity, int ltype)
  • image:需要標記的8位單通道圖像
  • labels:標記不同連通域后的輸出圖像
  • connectivity:標記連通域時的鄰域種類,8代表8鄰域,4代表4鄰域
  • ltype:輸出圖像的標簽類型,目前支持CV_32S和CV_16U
  • int返回值:連通域個數
public class ConnectedComponents {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo2/seed.png");HighGui.imshow("src", src);HighGui.waitKey(0);//將圖像轉位灰度圖并二值化Mat gray = new Mat();Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);Core.bitwise_not(gray, gray);//反相操作Mat binary = new Mat();Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);//在屏幕顯示二值圖HighGui.imshow("Binary", binary);HighGui.waitKey(0);//標記連通域Mat labels = new Mat(src.size(), CvType.CV_32S);//num為連通域個數int num = Imgproc.connectedComponents(binary, labels, 8, CvType.CV_32S);//定義顏色數組,用于不同的連通域Scalar[] colors = new Scalar[num];//隨機生成顏色Random rd = new Random();for (int i = 0; i < num; i++) {int r = rd.nextInt(256);int g = rd.nextInt(256);int b = rd.nextInt(256);colors[i] = new Scalar(r, g, b);}//標記各連通域,dst為用于標記的圖像Mat dst = new Mat(src.size(), src.type(), new Scalar(255, 255, 255));int width = src.cols();int height = src.rows();for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {//獲取標簽號int label = (int)labels.get(i, j)[0];//黑色背景色不變if (label == 0) {continue;}//根據標簽號設置顏色double[] val = new double[3];val[0] = colors[label].val[0];val[1] = colors[label].val[1];val[2] = colors[label].val[2];dst.put(i, j, val);}}//在屏幕上顯示最后結果HighGui.imshow("labelled", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:
在這里插入圖片描述

二值圖:
在這里插入圖片描述

用不同顏色標記后的連通域:

在這里插入圖片描述

//標記圖像中的連通域,并輸出統計信息
int Imgproc.connectedComponentsWithStats(Mat image, Mat labels, Mat stats, Mat centroids)
  • image:需要標記的8位單通道圖像
  • labels:標記不同連通域后的輸出圖像
  • stats:每個標簽的統計信息輸出,含背景標簽,數據類型為CV_32S
  • centroids:每個連通域的質心坐標,數據類型為CV_64F
public class ConnectedComponentsWithStats {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo2/seed.png");HighGui.imshow("src", src);HighGui.waitKey(0);//將圖像轉位灰度圖并二值化Mat gray = new Mat();Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY);Core.bitwise_not(gray, gray);//反相操作Mat binary = new Mat();Imgproc.threshold(gray, binary, 0, 255, Imgproc.THRESH_BINARY | Imgproc.THRESH_OTSU);//在屏幕顯示二值圖HighGui.imshow("Binary", binary);HighGui.waitKey(0);//標記連通域Mat labels = new Mat(src.size(), CvType.CV_32S);Mat stats = new Mat();Mat centroids = new Mat();int num = Imgproc.connectedComponentsWithStats(binary, labels, stats, centroids);//定義顏色數組,用于不同的連通域Scalar[] colors = new Scalar[num];//隨機生成顏色Random rd = new Random();for (int i = 0; i < num; i++) {int r = rd.nextInt(256);int g = rd.nextInt(256);int b = rd.nextInt(256);colors[i] = new Scalar(r, g, b);}//標記各連通域,dst為用于標記的圖像Mat dst = new Mat(src.size(), src.type(), new Scalar(255, 255, 255));int width = src.cols();int height = src.rows();for (int i = 0; i < height; i++) {for (int j = 0; j < width; j++) {//獲取標簽號int label = (int)labels.get(i, j)[0];//將背景以外的連通域設為黑色if (label != 0) {double[] val = new double[]{0, 0, 0};dst.put(i, j, val);}}}//繪制各連通域的質心和外接矩形for (int i = 1; i < num; i++) {//獲取連通域中心位置double cx = centroids.get(i, 0)[0];double cy = centroids.get(i, 1)[0];int left = (int)stats.get(i, Imgproc.CC_STAT_LEFT)[0];int top = (int)stats.get(i, Imgproc.CC_STAT_TOP)[0];width = (int)stats.get(i, Imgproc.CC_STAT_WIDTH)[0];height = (int)stats.get(i, Imgproc.CC_STAT_HEIGHT)[0];//繪制連通域質心Imgproc.circle(dst, new Point(cx, cy), 2, new Scalar(0, 0, 255), 2, 8, 0);//繪制連通域外接矩形Imgproc.rectangle(dst, new Point(left, top), new Point(left + width, top + height), colors[i], 2, 8, 0);}//在屏幕上顯示最后結果HighGui.imshow("labelled", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:
在這里插入圖片描述

二值化:
在這里插入圖片描述

標記質心和外接矩形的連通域圖:

在這里插入圖片描述

三、膨脹與腐蝕

3.1、結構元素

腐蝕和膨脹是形態(tài)學中最基本的操作,其他的形態(tài)學操作,如開運算、閉運算、頂帽、黑帽等,本質上都是腐蝕和膨脹的組合運算。形態(tài)學一般需要兩個輸入參數,一個是用于操作的圖像,另一個是類似卷積核的元素,稱為結構元素。結構元素還有一個用于定位的參考點,稱為錨點。

//根據指定的尺寸和形狀生成形態(tài)學操作的結構元素
Mat Imgproc.getStructuringElement(int shape, Size ksize, Point anchor)
  • shape:結構元素的形狀,有下列選項:
    • Imgproc.MORPH_RECT:矩形結構元素
    • Imgproc.MORPH_CROSS:十字型結構元素
    • Imgproc.MORPH_ELLIPSE:橢圓結構元素,矩形的內接橢圓
  • ksize:結構元素的尺寸
  • anchor:結構元素內的錨點,默認值(-1, -1),表示錨點位于結構元素中心。只有十字型的結構元素的形狀取決于錨點的位置。其他情況僅僅用于調節(jié)形態(tài)學操作結果的平移量。
public class StructureElement {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//矩形結構元素Mat k0 = Imgproc.getStructuringElement(0, new Size(3, 3));System.out.println(k0.dump());System.out.println();//十字型結構元素Mat k1 = Imgproc.getStructuringElement(1, new Size(3, 3));System.out.println(k1.dump());System.out.println();//橢圓結構元素Mat k2 = Imgproc.getStructuringElement(2, new Size(7, 7));System.out.println(k2.dump());System.out.println();}
}
[  1,   1,   1;1,   1,   1;1,   1,   1][  0,   1,   0;1,   1,   1;0,   1,   0][  0,   0,   0,   1,   0,   0,   0;0,   1,   1,   1,   1,   1,   0;1,   1,   1,   1,   1,   1,   1;1,   1,   1,   1,   1,   1,   1;1,   1,   1,   1,   1,   1,   1;0,   1,   1,   1,   1,   1,   0;0,   0,   0,   1,   0,   0,   0]

3.2、腐蝕

腐蝕是求局部最小值的操作。經過腐蝕操作后,圖像中的高亮區(qū)域會縮小,就像被腐蝕了一樣。

腐蝕運算的原理如下圖,原圖像標有1的像素為高亮區(qū)域,結構元素中心的像素為錨點。腐蝕操作時用結構元素掃描原圖像,用結構元素與覆蓋區(qū)域的像素進行與運算,如果所有像素的運算結果都是1,則該像素值為1,否則為0。

//原圖像
0 0 0 0 0 0 
0 0 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 0 0 0
0 0 1 1 0 0//結構元素
0 1 0
1 1 1
0 1 0//腐蝕運算結果
0 0 0 0 0 0 
0 0 0 0 0 0
0 0 1 1 0 0
0 0 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0

可以發(fā)現,原圖像中高亮區(qū)域有15像素,經過腐蝕操作后只有3像素了,所以的結構相當于給高亮區(qū)域瘦身,瘦身的效果取決于結構元素,而結構元素可以根據需求自行定義。需要注意的是,腐蝕操作及膨脹操作等形態(tài)學操作都是針對高亮區(qū)域。如果原圖像是黑白二值圖像,則被腐蝕的是白色區(qū)域,如果希望黑色區(qū)域被腐蝕,則可以在操作前先進行反向操作。

//用特定的結構元素對圖像進行腐蝕操作
void Imgproc.erode(Mat src, Mat dst, Mat kernel, Point anchor, int iterations)
  • src:輸入圖像,通道數任意,但深度應為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F
  • dst:輸出圖像,和src具有相同的尺寸和數據類型
  • kernel:用于腐蝕操作的結構元素,可以用getStructuringElement()函數生成
  • anchor:結構元素內錨點的位置,默認(-1, -1),表示錨點位于結構元素中心
  • iterations:腐蝕的次數

此方法可以設置迭代次數,即一次完成多次腐蝕操作。如果只需腐蝕一次,則可將后兩個參數省略。

public class Erode {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/wang.png");HighGui.imshow("src", src);HighGui.waitKey(0);//將圖像反向并顯示Core.bitwise_not(src, src);HighGui.imshow("negative", src);HighGui.waitKey(0);//生成十字型結構元素Mat kernel = Imgproc.getStructuringElement(1, new Size(3, 3));Point anchor = new Point(-1, -1);//腐蝕操作1次并顯示Mat dst = new Mat();Imgproc.erode(src, dst, new Mat());HighGui.imshow("erode=1", dst);HighGui.waitKey(0);//腐蝕操作3次并顯示Imgproc.erode(src, dst, kernel, anchor, 3);HighGui.imshow("erode=3", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:
在這里插入圖片描述

反向:
在這里插入圖片描述

一次腐蝕:

在這里插入圖片描述

三次腐蝕:
在這里插入圖片描述
上面的示例只能看到腐蝕的結構,無法對腐蝕的細節(jié)進行研究。下面用一個完整的程序說明:

public class Erode2 {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//構建一個6*6的小矩陣并導入數據Mat src = new Mat(6, 6, CvType.CV_8UC1);byte[] data = new byte[] {0,0,0,0,0,0,0,0,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0,0,1,1,0,0};src.put(0, 0, data);//打印矩陣System.out.println(src.dump());System.out.println();//構建十字型結構元素Mat kernel = Imgproc.getStructuringElement(1, new Size(3, 3));Mat dst = new Mat(6, 6, CvType.CV_8UC1);//進行腐蝕操作并輸出腐蝕后的矩陣Imgproc.erode(src, dst, kernel);System.out.println(dst.dump());}
}
[  0,   0,   0,   0,   0,   0;0,   0,   1,   1,   1,   0;0,   1,   1,   1,   1,   0;0,   1,   1,   1,   1,   0;0,   1,   1,   0,   0,   0;0,   0,   1,   1,   0,   0][  0,   0,   0,   0,   0,   0;0,   0,   0,   0,   0,   0;0,   0,   1,   1,   0,   0;0,   0,   1,   0,   0,   0;0,   0,   0,   0,   0,   0;0,   0,   0,   0,   0,   0]

3.3、膨脹

與腐蝕相反,膨脹則是求局部最大值的操作。經過膨脹操作后,圖像中的高亮區(qū)域會擴大,就像受熱膨脹一樣。膨脹運算原理如下,原圖像中標有1的像素為高亮區(qū)域,結構元素中心的像素為錨點。進行膨脹操作時用結構元素掃描原圖像,用結構元素與覆蓋區(qū)域的像素進行與運算,如果所有像素的運算結構都是0,則該像素值為0,否則為1。膨脹運算前高亮區(qū)域有15像素,經過膨脹操作后擴充為29像素,所以膨脹的結果讓高亮區(qū)域長胖了。

//原圖像
0 0 0 0 0 0
0 0 1 1 1 0
0 1 1 1 1 0
0 1 1 1 1 0
0 1 1 0 0 0
0 0 1 1 0 0//結構元素
0 1 0
1 1 1
0 1 0//膨脹運算結果
0 0 1 1 1 0
0 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 0
0 1 1 1 1 0
//用特定的結構元素對圖像進行膨脹操作
void Imgproc.dilate(Mat src, Mat dst, Mat kernel, Point anchor, int iterations)
  • src:輸入圖像,通道數任意,但深度應為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F
  • dst:輸出圖像,和src具有相同的尺寸和數據類型
  • kernel:用于膨脹操作的結構元素,可以用getStructuringElement()函數生成
  • anchor:結構元素內錨點的位置,默認(-1, -1),表示錨點位于結構元素中心
  • iterations:膨脹的次數
public class Dilate {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("F:/IDEAworkspace/opencv/src/main/java/demo/wang.png");HighGui.imshow("src", src);HighGui.waitKey(0);//將圖像反向并顯示Core.bitwise_not(src, src);HighGui.imshow("negative", src);HighGui.waitKey(0);//生成十字型結構元素Mat kernel = Imgproc.getStructuringElement(1, new Size(3, 3));Point anchor = new Point(-1, -1);//膨脹操作1次并顯示Mat dst = new Mat();Imgproc.dilate(src, dst, new Mat());HighGui.imshow("dilate=1", dst);HighGui.waitKey(0);//腐蝕操作3次并顯示Imgproc.dilate(src, dst, kernel, anchor, 3);HighGui.imshow("dilate=3", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:
在這里插入圖片描述

反向:

在這里插入圖片描述

膨脹一次:
在這里插入圖片描述

膨脹三次:
在這里插入圖片描述

四、形態(tài)學操作

腐蝕和膨脹操作時圖像形態(tài)學的基礎。通過對腐蝕和膨脹操作進行不同的組合可以實現圖像的開運算、閉運算、形態(tài)學梯度、頂帽運算、黑帽運算和擊中擊不中等操作。

這些操作在OpenCV中都使用morphologyEx()函數實現,只是其中的參數不同。該函數如下:

//對圖像進行基于腐蝕和膨脹的高級形態(tài)學操作
void Imgproc.morphologyEx(Mat src, Mat dst, int op, Mat kernel, Point anchor, int iterations)
  • src:輸入圖像,通道數任意,但深度應為CV_8U、CV_16U、CV_16S、CV_32F或CV_64F
  • dst:輸出圖像,和src具有相同的尺寸和數據類型
  • op:形態(tài)學操作的類型,具體有以下幾種:
    • Imgproc.MORPH_ERODE:腐蝕操作
    • Imgproc.MORPH_DILATE:膨脹操作
    • Imgproc.MORPH_OPEN:開運算
    • Imgproc.MORPH_CLOSE:閉運算
    • Imgproc.MORPH_GRADIENT:形態(tài)學梯度
    • Imgproc.MORPH_TOPHAT:頂帽運算
    • Imgproc.MORPH_BLACKHAT:黑帽運算
    • Imgproc.MORPH_HITMISS:擊中擊不中。只支持CV_8UC1類型的二值圖像
  • kernel:結構元素,可以用getStructuringElement函數生成
  • anchor:結構元素內錨點的位置,負數表示錨點位于結構元素中心
  • iterations:腐蝕和膨脹的次數

4.1、開運算和閉運算

開運算是對圖像先腐蝕后膨脹的過程,它可以用來去除噪聲、去除細小的形狀(如毛刺)或在輕微連接處分離物體等。腐蝕操作同樣能去掉毛刺,但是腐蝕操作后高亮區(qū)域整個廋了一圈,形態(tài)發(fā)生了明顯變化,而開運算能在去掉毛刺的同時又保持原來的大小。

與開運算相反的操作是閉預算。閉運算是對圖像先膨脹后腐蝕的過程。閉算遠可以去除小型空洞,還能將狹窄的缺口連接起來。

public class MorphologyEx1 {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/butterfly2.png");HighGui.imshow("src", src);HighGui.waitKey(0);Mat dst = new Mat();//閉運算1次并顯示Point anchor = new Point(-1, -1);Imgproc.morphologyEx(src, dst, Imgproc.MORPH_CLOSE, new Mat(), anchor, 1);HighGui.imshow("Close-1", dst);HighGui.waitKey(0);//閉運算3次并顯示Imgproc.morphologyEx(src, dst, Imgproc.MORPH_CLOSE, new Mat(), anchor, 3);HighGui.imshow("Close-3", dst);HighGui.waitKey(0);//在3次閉運算的基礎上進行開運算并顯示Imgproc.morphologyEx(dst, dst, Imgproc.MORPH_OPEN, new Mat(), anchor, 1);HighGui.imshow("Open", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:
在這里插入圖片描述

閉運算1次:
在這里插入圖片描述

閉運算3次:
在這里插入圖片描述

開運算一次:
在這里插入圖片描述

輸入圖像是一只蝴蝶的輪廓圖,經過1次閉運算后部分空洞消失,3次閉運算后大量空洞消失,在此基礎上進行1次開運算使很多輪廓線消失。

4.2、頂帽和黑帽

頂帽運算也稱為禮貌運算,是計算原圖像與開運算結果之差的操作。由于開運算后放大了裂縫或者局部低亮度的區(qū)域,從原圖中減去開運算后的圖像后就突出了比原圖像輪廓周邊區(qū)域更明亮的區(qū)域。

黑帽運算則是計算閉運算結果與原圖像之差的操作。黑帽運算后突出了比原圖像輪廓周邊區(qū)域更暗的區(qū)域。

public class MorphologyEx2 {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像并顯示Mat src = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/shaomai.png");HighGui.imshow("src", src);HighGui.waitKey(0);Mat dst = new Mat();//轉換為二值圖并顯示Imgproc.threshold(src, src, 120, 255, Imgproc.THRESH_BINARY);HighGui.imshow("Binary", src);HighGui.waitKey(0);//頂帽運算3次并顯示Point anchor = new Point(-1, -1);Imgproc.morphologyEx(src, dst, Imgproc.MORPH_TOPHAT, new Mat(), anchor, 3);HighGui.imshow("Tophat", dst);HighGui.waitKey(0);//黑帽運算3次并顯示Imgproc.morphologyEx(src, dst, Imgproc.MORPH_BLACKHAT, new Mat(), anchor, 3);HighGui.imshow("Blackhat", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖:

在這里插入圖片描述

二值圖:

在這里插入圖片描述

頂帽3次:

在這里插入圖片描述

黑帽3次:

在這里插入圖片描述

4.3、形態(tài)學梯度

形態(tài)學梯度是計算膨脹結果與腐蝕結果之差的操作,其結果看上去就像圖像的輪廓。

public class MorphologyEx3 {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//讀取圖像1并顯示Mat src1 = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/shaomai.png");HighGui.imshow("src1", src1);HighGui.waitKey(0);//形態(tài)學梯度并顯示Point anchor = new Point(-1, -1);Mat dst = new Mat();Imgproc.morphologyEx(src1, dst, Imgproc.MORPH_GRADIENT, new Mat(), anchor, 1);HighGui.imshow("Gradient1", dst);HighGui.waitKey(0);//讀取圖像2并顯示Mat src2 = Imgcodecs.imread("/Users/acton_zhang/J2EE/MavenWorkSpace/opencv_demo/src/main/java/demo1/wang.png", Imgcodecs.IMREAD_GRAYSCALE);HighGui.imshow("src2", src2);HighGui.waitKey(0);//形態(tài)學梯度并顯示Imgproc.morphologyEx(src2, dst, Imgproc.MORPH_GRADIENT, new Mat(), anchor, 1);HighGui.imshow("Gradient2", dst);HighGui.waitKey(0);System.exit(0);}
}

原圖1:
在這里插入圖片描述

形態(tài)學梯度:

在這里插入圖片描述

原圖2:
在這里插入圖片描述

形態(tài)學梯度:

在這里插入圖片描述

4.4、擊中擊不中

擊中擊不中運算常用于二值圖像,它的要求比腐蝕操作還要嚴格。只有當結構元素與其覆蓋的區(qū)域完全相同時,該像素才為1,否則為0,如下:

//原圖
0 0 0 0 0 0
0 1 1 1 1 0
0 1 1 0 1 0
0 1 1 1 1 1
0 0 0 0 0 0//結構元素
1 1 1
1 0 1
1 1 1//擊中擊不中結果
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 1 0 0 
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
public class HitMiss {static {OpenCV.loadLocally(); // 自動下載并加載本地庫}public static void main(String[] args) {//構建一個6*6的小矩陣并導入數據Mat src = new Mat(6, 6, CvType.CV_8UC1);byte[] data = new byte[] {0, 0, 0, 0, 0, 0,0, 0, 1, 1, 1, 0,0, 1, 1, 1, 1, 0,0, 1, 1, 1, 1, 0,0, 1, 1, 0, 0, 0,0, 0, 1, 1, 0, 0};src.put(0, 0, data);//打印矩陣輸出System.out.println(src.dump());System.out.println();//構建矩形結構元素并輸出Mat kernel = Imgproc.getStructuringElement(0, new Size(3, 3));System.out.println(kernel.dump());System.out.println();//擊中擊不中測試并輸出Point anchor = new Point(-1, -1);Mat dst = new Mat(6, 6, CvType.CV_8UC1);Imgproc.morphologyEx(src, dst, Imgproc.MORPH_HITMISS, kernel, anchor, 1);System.out.println(dst.dump());}
}
[  0,   0,   0,   0,   0,   0;0,   0,   1,   1,   1,   0;0,   1,   1,   1,   1,   0;0,   1,   1,   1,   1,   0;0,   1,   1,   0,   0,   0;0,   0,   1,   1,   0,   0][  1,   1,   1;1,   1,   1;1,   1,   1][  0,   0,   0,   0,   0,   0;0,   0,   0,   0,   0,   0;0,   0,   0,   1,   0,   0;0,   0,   0,   0,   0,   0;0,   0,   0,   0,   0,   0;0,   0,   0,   0,   0,   0]
http://www.risenshineclean.com/news/55695.html

相關文章:

  • 兩學一做注冊網站百度首頁
  • 網站開發(fā)文檔撰寫模板鎮(zhèn)江seo
  • 阿里云做網站需要環(huán)境自己做一個網站要多少錢
  • 沈陽市建設工程質量監(jiān)督局網站神馬推廣登錄
  • 職業(yè)生涯規(guī)劃用什么網站做測試微博搜索引擎優(yōu)化
  • 做網站最適合用多大的圖片手游代理加盟哪個平臺最強大
  • 網站和做游戲網站優(yōu)化排名服務
  • 專業(yè)官網設計周口seo公司
  • 備案網站名怎么寫uc信息流廣告投放
  • 游戲模型外包網站推廣公司品牌
  • 網站建設 銷售百度愛采購推廣怎么收費
  • 做導航網站有發(fā)展嗎東莞市網絡seo推廣企業(yè)
  • 網站免備案空間北京搜索排名優(yōu)化
  • 連云港集團網站建設企業(yè)快速建站
  • 企業(yè)網站seo哪里好百度關鍵詞seo排名軟件
  • 政府網站建設預算百度百科詞條入口
  • php響應式個人博客網站設計網站建設制作流程
  • 重慶企業(yè)網站建站app推廣拉新一手渠道代理
  • 做網站能收多少廣告費軟件推廣賺錢一個10元
  • 網站建設項目seo網絡推廣企業(yè)
  • 教育網站建設的意義推廣渠道有哪些
  • 用eclipse編程做網站網絡營銷的基本方法
  • 人民日報新聞評論寧波seo關鍵詞優(yōu)化
  • 188旅游網站管理系統百度下載并安裝最新版
  • 蛋糕店網站建設深圳百度推廣關鍵詞推廣
  • 合肥網站改版做銷售怎樣去尋找客戶
  • layui 企業(yè)網站模板全網營銷思路
  • 用阿里云服務器做盜版小說網站嗎如何seo推廣
  • 黨校網站信息化建設整改情況百度自動點擊器
  • 建站最便宜的平臺推廣注冊app拿傭金