opencv实战,钢板焊接点寻找4,求助

2019-07-14 08:50发布

第四张图使带火花的,因为焊接过程中有火花的干扰,而且影响很大。

火花对图像的影响很大,大的火花直接把钢板一些特征给影响了。 我的第一个思路是:用轮廓提取,计算轮廓面积,在一定范围内的认为使钢板,把钢板那部分复制到另一幅空图上(大小和原图一样),在提取中间焊接点,但大的火花会对图像有影响。 代码如下:(只写了一部分,计算了轮廓的矩) #include #include "opencv2/highgui/highgui.hpp" #include "opencv2/imgproc/imgproc.hpp" #include #include using namespace cv; using namespace std; #define WINDOW_NAME "【亚像素级角点检测】" Mat g_srcImage, g_grayImage; int g_maxCornerNumber = 20; //点数初始值 int g_maxTrackbarNumber = 500; //点数上线 //RNG g_rng(12345); //初始化随机数生成器 void on_GoodFeaturesToTrack(int, void*) //响应滑动条移动的回调函数 { if (g_maxCornerNumber <= 7) { g_maxCornerNumber = 7; } //对变量小于等于1时的处理 vector corners; //Shi-Tomasi算法(goodFeaturesToTrack函数)的参数准备 double qualityLevel = 0.01; //角点检测可接受的最小特征值 double minDistance = 10; //角点之间的最小距离 int blockSize = 3; //计算导数自相关矩阵时指定的邻域范围 double k = 0.04; //权重系数 Mat copy = g_srcImage.clone(); //进行Shi-Tomasi角点检测 goodFeaturesToTrack (g_grayImage, //输入图像 corners, //检测到的角点的输出向量 g_maxCornerNumber, //角点的最大数量 qualityLevel, //角点检测可接受的最小特征值 minDistance, //角点之间的最小距离 Mat(), //感兴趣区域 blockSize, //计算导数自相关矩阵时指定的邻域范围 false, //不使用Harris角点检测 k); //权重系数 cout << " >-此次检测到的角点数量为:" << corners.size() << endl; //亚像素角点检测的参数设置 Size winSize = Size(5, 5); Size zeroZone = Size(-1, -1); TermCriteria criteria = TermCriteria(TermCriteria::EPS + TermCriteria::MAX_ITER, 40, 0.001); //计算出亚像素角点位置 cornerSubPix(g_grayImage, corners, winSize, zeroZone, criteria); for (int i = 0; i < corners.size(); i++) { circle(copy, corners[i], 3, Scalar(0, 255, 0), -1, 8, 0); cout << " >>点坐标[" << i << "] (" << corners[i].x << "," << corners[i].y << ")" << endl; } imshow(WINDOW_NAME, copy); } int main(int argc, char** argv) { Mat srcImage = imread("4.jpg", 0); //载入原始图二值图模式 imshow("原始图", srcImage); Mat element = getStructuringElement(MORPH_RECT, Size(2,2)); //定义核,开运算 morphologyEx(srcImage, srcImage, MORPH_OPEN, element); //进行形态学开运算操作 Mat dstImage = Mat::zeros(srcImage.rows, srcImage.cols, CV_8UC3); //初始化结果图 srcImage = srcImage > 80; //srcImage取大于阈值。。。那部分 imshow("取阈值后的原始图", srcImage); vector > contours; vector hierarchy; findContours(srcImage, contours, hierarchy, RETR_CCOMP, CHAIN_APPROX_SIMPLE); vector mu(contours.size()); // 计算矩 for (unsigned int i = 0; i < contours.size(); i++) { mu[i] = moments(contours[i], false); } int index = 0; //遍历所有顶层的轮廓, 以随机颜 {MOD}绘制出每个连接组件颜 {MOD} for (; index >= 0; index = hierarchy[index][0]) { Scalar color(rand() & 255, rand() & 255, rand() & 255); drawContours(dstImage, contours, index, color, FILLED, 8, hierarchy); } printf(" 输出内容: 面积和轮廓长度 "); // 通过m00计算轮廓面积并且和OpenCV函数比较 for (unsigned int i = 0; i< contours.size(); i++) { printf(" >通过m00计算出轮廓[%d]的面积: (M_00) = %.2f OpenCV函数计算出的面积=%.2f , 长度: %.2f ", i, mu[i].m00, contourArea(contours[i]), arcLength(contours[i], true)); } system("color 2F"); g_srcImage = dstImage; cvtColor(g_srcImage, g_grayImage, COLOR_BGR2GRAY); namedWindow(WINDOW_NAME, WINDOW_AUTOSIZE); //创建窗口和滑动条,并进行显示和回调函数初始化 createTrackbar("最大角点数", WINDOW_NAME, &g_maxCornerNumber, g_maxTrackbarNumber, on_GoodFeaturesToTrack); on_GoodFeaturesToTrack(0, 0); waitKey(0); return 0; }
结果显示可以提取钢板的面积,但是有可能大的火花正好挡住角点,这种方法就不行了,就没有继续做下去。

我想出第二种方法,但是要有视频文件才行,思路是:用背景去除法比较视频前一帧和后第a帧(保证火花在这a帧时间内从一个位置到另个位置)。这样火花就可以提取出来,在把火花和后第a帧图像比较,从而去除火花,进一步处理钢板上的特征。时间关系就没有做这一部分。 现在求助,希望大家能有更好的建议。