最近做了一个钢板焊接点寻找项目,记录一下,哈哈
分为3张图,分成3个博客讲。分别寻找焊接点,因为没有视频,只能从图片中提取。
还有一个问题要求助在第四个博客,我想出一个方法,看看大家有没有什么更好的办法,相互学习。
第一张图,
方法是调滤波迭代值,加houghlinesP(轮廓)。
系统win10,64位,IDE:VS2015。
代码如下:
//调滤波迭代值,加houghlinesP(轮廓)
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
Mat g_srcImage, g_dstImage;//原始图和效果图
int g_nElementShape = MORPH_RECT;//元素结构的形状
int g_nMaxIterationNum = 10;
int g_nOpenCloseNum = 0;
static void on_OpenClose(int, void*);//回调函数
static void ShowHelpText();
int main()
{
system("color 2F");
ShowHelpText();
g_srcImage = imread("1.jpg");
if (!g_srcImage.data) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
namedWindow("【开运算/闭运算】", 1);
g_nOpenCloseNum = 21;//9
createTrackbar("迭代值", "【开运算/闭运算】", &g_nOpenCloseNum, g_nMaxIterationNum * 2 + 1, on_OpenClose);
//轮询获取按键信息
while (1)
{
int c;
on_OpenClose(g_nOpenCloseNum, 0);
c = waitKey(0); //获取按键
if ((char)c == 'q' || (char)c == 27) //按下键盘按键Q或者ESC,程序退出
break;
if ((char)c == 49) //键盘按键1的ASII码为49,按下键盘按键1,使用椭圆(Elliptic)结构元素结构元素MORPH_ELLIPSE
g_nElementShape = MORPH_ELLIPSE;
else if ((char)c == 50) //键盘按键2的ASII码为50,按下键盘按键2,使用矩形(Rectangle)结构元素MORPH_RECT
g_nElementShape = MORPH_RECT;
else if ((char)c == 51) //键盘按键3的ASII码为51,按下键盘按键3,使用十字形(Cross-shaped)结构元素MORPH_CROSS
g_nElementShape = MORPH_CROSS;
else if ((char)c == ' ')
g_nElementShape = (g_nElementShape + 1) % 3; //按下键盘按键space,在矩形、椭圆、十字形结构元素中循环
}
return 0;
}
// 【开运算/闭运算】窗口的回调函数
static void on_OpenClose(int, void*)
{
int offset = g_nOpenCloseNum - g_nMaxIterationNum; //偏移量
int Absolute_offset = offset > 0 ? offset : -offset; //偏移量绝对值
Mat element = getStructuringElement(g_nElementShape, Size(Absolute_offset * 2 + 1, Absolute_offset * 2 + 1), Point(Absolute_offset, Absolute_offset)); //自定义核
if (offset < 0)
morphologyEx(g_srcImage, g_dstImage, MORPH_OPEN, element);
else
morphologyEx(g_srcImage, g_dstImage, MORPH_CLOSE, element);
imshow("【开运算/闭运算】", g_dstImage);
//加houghlinesP
Mat srcImage = g_dstImage;
Mat midImage, dstImage; //中间变量和目标图
Canny(srcImage, midImage, 50, 200, 3);
cvtColor(midImage, dstImage, COLOR_GRAY2BGR); //转化为灰度图
vector<Vec4i> lines;
HoughLinesP(midImage, lines, 1, CV_PI / 180, 20, 20, 20); //(输入二值图像,储存线条矢量,距离精度,角度精度,阈值参数(大于阈值才可以被检测返回),最低线段长度(比这个参数短的不能显示),允许同一行点与点连接的最大距离)
for (size_t i = 0; i < lines.size(); i++) //依次在图中绘制出每条线段
{
Vec4i l = lines[i];
//斜率过滤
float k = 1.0*(l[3]-l[1])/(l[2]-l[0]);
int slop = abs(k);
Point a;
if (slop <1) //底线
{
}
else if(slop >= 1)
{
line(dstImage, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(10, 0, 255), 1, LINE_AA);
Point a((l[0]+l[2])/2, (l[1] + l[3]) / 2);
circle(dstImage, a, 3, Scalar(0, 255, 0),2);
cout << "坐标为(" <<(l[0]+l[2])/2 << "," << (l[0] + l[2]) / 2 << ")" << endl;
}
}
imshow("【效果图】", dstImage);
}
static void ShowHelpText()
{
printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION);
//帮助信息
printf("\n\t按键操作说明: \n\n"
"\t\t键盘按键【ESC】或者【Q】- 退出程序\n"
"\t\t键盘按键【1】- 使用椭圆(Elliptic)结构元素\n"
"\t\t键盘按键【2】- 使用矩形(Rectangle )结构元素\n"
"\t\t键盘按键【3】- 使用十字型(Cross-shaped)结构元素\n"
"\t\t键盘按键【空格SPACE】- 在矩形、椭圆、十字形结构元素中循环\n");
}
结果:
希望大家能给出更好的建议