# canny边缘检测
void cv::Canny ( InputArray image,//输入图像(单通道灰度图)
OutputArray edges,//检测出来的轮廓
double threshold1,//阈值1
double threshold2,//阈值2
int apertureSize = 3,//Sobel 算子内核大小
bool L2gradient = false //不使用更精确的L2范数进行计算
)
#统计霍夫曼
void HoughLinesP(InputArray image, //输入图像
OutputArray lines, //存放线上两点坐标的容器
double rho, //极径 r 以像素值为单位的分辨率
double theta,//极角 θ 以弧度为单位的分辨率
int threshold, //检测为一条直线最少的交点个数
double minLineLength=0,//组成一条线最小点的数量
double maxLineGap=0 //线上最近两点间的距离
)
显示一张图片,鼠标框选图片中的角,就能及时显示角度大小。
float find_angle(vector<Vec4i> lines)//计算容器里面所有向量的最大角度限制在90°以内
{
int i, ii;
int length = lines.size();
int times = 1;
float angle = 0, angle_max = 0.0;
for (i = 0; i < lines.size() - 1; i++)//便利找出所有向量间最大的角度
{
for (ii = i + 1; ii < lines.size(); ii++)
{
float vector1x = lines[i][0] - lines[i][2];
float vector1y = lines[i][1] - lines[i][3];
float vector2x = lines[ii][0] - lines[ii][2];
float vector2y = lines[ii][1] - lines[ii][3];
angle = acosf(abs(((vector1x)*(vector2x)+(vector1y)*(vector2y)) / (sqrt(pow(vector1x, 2) + pow(vector1y, 2))*sqrt(pow(vector2x, 2) + pow(vector2y, 2)))));
}
if (angle > angle_max && angle <=(CV_PI/2))//避免角度大于90度的情况
{
angle_max = angle;
}
}
return angle_max * 180 / CV_PI;
}
Point win_s(-1,-1);//用来存储选框的坐标
Point win_e;
void line_draw(int event, int x, int y, int flags, void *userdata)//鼠标回调函数
{
Mat src = *(Mat*)userdata;
Mat pic;
src.copyTo(pic);
if (event == EVENT_LBUTTONDOWN)//鼠标按下
{
win_s.x = x;
win_s.y = y;
std::cout << "start point:" << sp << std::endl;
}
else if (event == EVENT_MOUSEMOVE)//鼠标移动
{
printf("move\n");
if (win_s.x >= 0 || win_s.y >= 0)
{
win_e.x = x;
win_e.y = y;
if ((win_e.x - win_s.x) >= 0 && (win_e.y - win_s.y) >= 0)
{
Rect rec(win_s.x, win_s.y, win_e.x - win_s.x, win_e.y - win_s.y);
rectangle(pic, rec, Scalar(0, 0, 255), 1, 8, 0);
}
imshow("dst", pic);
}
}
else if (event == EVENT_LBUTTONUP)//鼠标按键松开
{
printf("over");
win_e.x = x;
win_e.y = y;
std::cout << "end point:" << ep << std::endl;
if ((win_e.x - win_s.x) >= 0 && (win_e.y - win_s.y) >= 0)
{
Rect rec(win_s.x, win_s.y, win_e.x - win_s.x, win_e.y - win_s.y);
Mat circle_area = pic(rec);
Mat dst, dst1;
vector<Vec4i> lines;
//bilateralFilter(circle_area, dst, 0, 10, 10);//高斯滤波
Canny(circle_area, dst1, 50, 200, 3);//用Canny算子对图像进行边缘检测
HoughLinesP(dst1, lines, 1, CV_PI / 180, 20, 20, 1);
int ii = 0;
for (size_t i = 0; i < lines.size(); i++)//把选框内的所有线画出来
{
Vec4i pos = lines[i];
line(pic, Point(pos[0] + win_s.x, pos[1] + win_s.y), Point(pos[2] + win_s.x, pos[3] + win_s.y), Scalar(255, 0, 0), 3, 8, 0);
ii++;
}
printf("lines:%d,angle:%f", ii, find_angle(lines));
putText(pic, to_string(find_angle(lines)), win_s, FONT_HERSHEY_PLAIN, 5, Scalar(0, 0, 255), 2, 8, false);
}
imshow("dst", pic);
win_s.x = -1;
win_s.y = -1;
}
}
void Demo::line_detection(Mat pic)//总的函数
{
namedWindow("dst", WINDOW_NORMAL);
Mat src = imread("D:/DESKTOP/picture/angle.png");
imshow("dst", src);
setMouseCallback("dst", line_draw, &src);//设定鼠标回调函数
waitKey(0);
}