日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

opencv实现二值图像孔洞填充

發布時間:2023/12/29 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 opencv实现二值图像孔洞填充 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? matlab中的imfill函數可以方便得實現二值圖像的孔洞填充,而在opencv中并沒有相同功能的函數。因此,在opencv的基礎上編寫實現孔洞填充的函數,并且能夠設定閾值,對面積大于閾值的孔洞不進行填充。使用形態學重建的算法能夠有效地實現孔洞填充,具體算法參照《數字圖像處理》第三版9.5.9節,孔洞填充。

? ? 主要實現代碼如下所示:其中imfill函數即為空洞填充的實現函數,第一個參數是二值圖像(0~1),第二個參數是填充孔洞的閾值。若孔洞面積大于閾值則不填充,反之則填充。

#include "iostream" #include <opencv2\opencv.hpp> using namespace std; using namespace cv; Mat inv_board(Mat src); Mat inv_img(Mat src); void delarea(Mat& bw, int max); Mat imfill(Mat I, int max); void main() {Mat scr = imread("2.png");Mat I, src_gray, F_B, F_BI_C, temp, H, I_fill;cvtColor(scr, src_gray, COLOR_BGR2GRAY);threshold(src_gray, I, 0.1, 1,0);I_fill = imfill(I,40);imshow("原二值圖", I * 255);imshow("填充圖", I_fill*255);waitKey(0); }Mat imfill(Mat I,int max) {Mat src_gray, F_B, F_BI_C, temp, H, I_fill;I_fill = I.clone();Mat F = inv_board(I);Mat I_C = inv_img(I);Mat element = getStructuringElement(0, Size(3, 3), Point(1, 1));while (1){dilate(F, F_B, element);F_BI_C = F_B.mul(I_C);temp = F_BI_C - F;if (sum(temp) == Scalar(0))break;elseF = F_BI_C.clone();}H = inv_img(F_BI_C);Mat H_IC = H.mul(I_C);delarea(H_IC, max);for (int i = 0; i < H_IC.rows; i++){for (int j = 0; j < H_IC.cols; j++){if (H_IC.at<uchar>(i, j) == 1)I_fill.at<uchar>(i, j) = 1;}}return I_fill; } Mat inv_board(Mat src) {int rows = src.rows;int cols = src.cols;Mat dst = Mat::zeros(rows, cols, CV_8UC1);for (int i = 0; i < cols; i++){dst.at<uchar>(0, i) = 1 - src.at<uchar>(0, i);}for (int i = 0; i < cols; i++){dst.at<uchar>(rows-1, i) = 1 - src.at<uchar>(rows - 1, i);}for (int i = 1; i < rows-1; i++){dst.at<uchar>(i, 0) = 1 - src.at<uchar>(i, 0);}for (int i = 1; i < rows - 1; i++){dst.at<uchar>(i, cols-1) = 1 - src.at<uchar>(i, cols-1);}return dst; }Mat inv_img(Mat src) {int rows = src.rows;int cols = src.cols;Mat dst = src.clone();for (int i = 0; i < rows; i++)for (int j = 0; j < cols; j++)dst.at<uchar>(i, j) = 1 - src.at<uchar>(i, j);return dst; }void delarea(Mat& bw, int max ) {Mat bw_copy = bw.clone();int flag = 0; Mat H_b, H_bw, temp;Mat H = Mat::zeros(bw.size(), bw.type());for (int i = 0; i < bw.rows; i++){for (int j = 0; j < bw.cols; j++){if (bw_copy.at<uchar>(i, j) == 1){H.at<uchar>(i, j) = 1;Mat element = getStructuringElement(0, Size(3, 3), Point(1, 1));while (1){dilate(H, H_b, element); H_bw = H_b.mul(bw);temp = H_bw - H;if (sum(temp) == Scalar(0))break;elseH = H_bw.clone();}bw_copy = bw_copy - H_bw;if (sum(H_bw).val[0] > max){bw = bw - H_bw;}H = Mat::zeros(bw.size(), bw.type());}}} }


總結

以上是生活随笔為你收集整理的opencv实现二值图像孔洞填充的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。