如有問題請聯繫:[email protected]
更多文章請關注微信公衆號:機器視覺專業論壇
在實際應用中,得到的圖像的閾值不太理想時通過固定閾值分割很難得到所要提取的特徵,因此Halcon中含有動態閾值分割法,即首先對圖像進行均值濾波,然後與現有圖像最差後進行閾值分割。該方法適合比較小的特徵提取,例如金屬表面的劃痕、絲網的漏洞等。
本例提取絲網上漏洞區域以及漏洞數量,主要步驟如下:
1.對讀入的圖像進行動態閾值分割,分割出Blob區域。
2.利用面積對Blob區域進行選擇。
3.顯示檢測結果。
本例的主要收穫如下:
1.熟悉了動態閾值分割的使用方法,在Opencv環境下采用blur、subtract、threshold三個算子實現了動態閾值分割。
2.類Moments的使用,零階距.m00表示輪廓的面積,.m10爲輪廓重心。另外contourArea也表示求輪廓面積,arcLength求輪廓周長。
3.drawContours方法可以實際畫到原圖像上在顯示。drawContours的參數Thickness爲CV_FILLED(-1)時表示對輪廓進行填充
當它爲正數時表示線寬,該方法可以繪出或者分割出Blob區域。
#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/features2d.hpp"
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
cv::Mat image,imagemean, diff, Mask;
image = imread("../data/plastic_mesh/plastic_mesh_07.png");
blur(image, imagemean, Size(49, 49));
subtract(image, imagemean, diff);
threshold(diff, Mask, 5, 255, THRESH_BINARY_INV);//同動態閾值分割dyn_threshold
Mat imagegray;
cvtColor(Mask, imagegray, CV_RGB2GRAY);
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
findContours(imagegray, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
Mat drawing = Mat::zeros(Mask.size(), CV_8U);
int j = 0;
Mat MM;
for (int i = 0; i < contours.size(); i++)
{
Moments moms = moments(Mat(contours[i]));
double area = moms.m00; //零階矩即爲二值圖像的面積 double area = moms.m00;
//如果面積超出了設定的範圍,則不再考慮該斑點
if (area > 500 && area < 90000)
{
drawContours(image, contours, i, Scalar(0, 0, 255), 2, 8, hierarchy, 0, Point());
j = j + 1;
}
}
char t[256];
sprintf_s(t, "%01d",j);
string s = t;
string txt = "Number of NG : " + s;
putText(image, txt, Point(20, 30), CV_FONT_HERSHEY_COMPLEX, 1,
Scalar(0, 0, 255), 2, 8);
imshow("漏洞", image);
waitKey();
return 0;
}
“`