sobel算子和scharr滤波器
Scharr的Ksize固定是3,下面是一个把这几个算子的集中展示
Mat g_srcImage, g_srcGrayImage, g_dstImage;
//Canny边缘检测相关变量
Mat g_cannyDetectedEdges;
int g_cannyLowThreshold = 1;//TrackBar位置参数
//Sobel边缘检测相关变量
Mat g_sobelGradient_X, g_sobelGradient_Y;
Mat g_sobelAbsGradient_X, g_sobelAbsGradient_Y;
int g_sobelKernelSize = 1;//TrackBar位置参数
//Scharr滤波器相关变量
Mat g_scharrGradient_X, g_scharrGradient_Y;
Mat g_scharrAbsGradient_X, g_scharrAbsGradient_Y;
static void on_Canny(int, void*);//Canny边缘检测窗口滚动条的回调函数
static void on_Sobel(int, void*);//Sobel边缘检测窗口滚动条的回调函数
void Scharr();//封装了Scharr边缘检测相关代码的函数
int main(int argc, char** argv)
{
//改变console字体颜色
system("color 2F");
//载入原图
g_srcImage = imread("dota_pa.jpg");
if (!g_srcImage.data) { printf("Oh,no,读取srcImage错误~! \n"); return false; }
//显示原始图
namedWindow("【原始图】");
imshow("【原始图】", g_srcImage);
// 创建与src同类型和大小的矩阵(dst)
g_dstImage.create(g_srcImage.size(), g_srcImage.type());
// 将原图像转换为灰度图像
cvtColor(g_srcImage, g_srcGrayImage, COLOR_BGR2GRAY);
// 创建显示窗口
namedWindow("【效果图】Canny边缘检测", WINDOW_AUTOSIZE);
namedWindow("【效果图】Sobel边缘检测", WINDOW_AUTOSIZE);
// 创建trackbar
createTrackbar("参数值:", "【效果图】Canny边缘检测", &g_cannyLowThreshold, 120, on_Canny);
createTrackbar("参数值:", "【效果图】Sobel边缘检测", &g_sobelKernelSize, 3, on_Sobel);
// 调用回调函数
on_Canny(0, 0);
on_Sobel(0, 0);
//调用封装了Scharr边缘检测代码的函数
Scharr();
//轮询获取按键信息,若按下Q,程序退出
while ((char(waitKey(1)) != 'q')) {}
return 0;
}
//-----------------------------------【on_Canny( )函数】----------------------------------
// 描述:Canny边缘检测窗口滚动条的回调函数
//-----------------------------------------------------------------------------------------------
void on_Canny(int, void*)
{
// 先使用 3x3内核来降噪
blur(g_srcGrayImage, g_cannyDetectedEdges, Size(3, 3));
// 运行我们的Canny算子
Canny(g_cannyDetectedEdges, g_cannyDetectedEdges, g_cannyLowThreshold, g_cannyLowThreshold * 3, 3);
//先将g_dstImage内的所有元素设置为0
g_dstImage = Scalar::all(0);
//使用Canny算子输出的边缘图g_cannyDetectedEdges作为掩码,来将原图g_srcImage拷到目标图g_dstImage中
g_srcImage.copyTo(g_dstImage, g_cannyDetectedEdges);
//显示效果图
imshow("【效果图】Canny边缘检测", g_dstImage);
}
//-----------------------------------【on_Sobel( )函数】----------------------------------
// 描述:Sobel边缘检测窗口滚动条的回调函数
//-----------------------------------------------------------------------------------------
void on_Sobel(int, void*)
{
// 求 X方向梯度
Sobel(g_srcImage, g_sobelGradient_X, CV_16S, 1, 0, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
convertScaleAbs(g_sobelGradient_X, g_sobelAbsGradient_X);//计算绝对值,并将结果转换成8位
// 求Y方向梯度
Sobel(g_srcImage, g_sobelGradient_Y, CV_16S, 0, 1, (2 * g_sobelKernelSize + 1), 1, 1, BORDER_DEFAULT);
convertScaleAbs(g_sobelGradient_Y, g_sobelAbsGradient_Y);//计算绝对值,并将结果转换成8位
// 合并梯度
addWeighted(g_sobelAbsGradient_X, 0.5, g_sobelAbsGradient_Y, 0.5, 0, g_dstImage);
//显示效果图
imshow("【效果图】Sobel边缘检测", g_dstImage);
}
//-----------------------------------【Scharr( )函数】----------------------------------
// 描述:封装了Scharr边缘检测相关代码的函数
//-----------------------------------------------------------------------------------------
void Scharr()
{
// 求 X方向梯度
Scharr(g_srcImage, g_scharrGradient_X, CV_16S, 1, 0, 1, 0, BORDER_DEFAULT);
convertScaleAbs(g_scharrGradient_X, g_scharrAbsGradient_X);//计算绝对值,并将结果转换成8位
// 求Y方向梯度
Scharr(g_srcImage, g_scharrGradient_Y, CV_16S, 0, 1, 1, 0, BORDER_DEFAULT);
convertScaleAbs(g_scharrGradient_Y, g_scharrAbsGradient_Y);//计算绝对值,并将结果转换成8位
// 合并梯度
addWeighted(g_scharrAbsGradient_X, 0.5, g_scharrAbsGradient_Y, 0.5, 0, g_dstImage);
//显示效果图
imshow("【效果图】Scharr滤波器", g_dstImage);
}
霍夫变换
主要说一下累计概率霍夫HoughLinesP
HoughLinesP(mid,lines,1,CV_PI/180,80,50,10);
输入:8位单通道,输出:lines,输出矢量,每一条线会输出四个矢量,分别是检测到线段的起点终点坐标;像素为单位的位移步长;角度步长;阈值;最低线段长度;MaxLineGap,最大的连接点的距离,如下:
Mat img = imread("dota_pa.jpg");
Mat mid, dst;
Canny(img, mid, 50, 200);
cvtColor(mid, dst, COLOR_GRAY2BGR);
vector<Vec4i>lines;//设置一个矢量结构来装lines,Vec4i原码typedef Vec<int, 4> Vec4i;
HoughLinesP(mid,lines,1,CV_PI/180,80,50,10);
for (size_t i=0; i < lines.size(); i++) {
Vec4i l = lines[i];
line(dst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0, 255, 0), 1, 8);
}
imshow("1", dst);
waitKey(0);
霍夫圆
霍夫圆的源图不需要是二值的,而直线的需要
Mat img = imread("yuan.jpg");
Mat mid, dst;
cvtColor(img, mid, COLOR_BGR2GRAY);
GaussianBlur(mid, mid, Size(9, 9), 2, 2);
vector<Vec3f>circles;
HoughCircles(mid, circles, HOUGH_GRADIENT, 1.5, 10, 200, 100);
for (size_t i = 0; i < circles.size(); i++) {
Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
int radius = cvRound(circles[i][2]);
circle(img, center, radius, Scalar(0, 255, 0));
}
第二个参数是个三个元素的矢量,也是用vector,(x,y,r);第三个参数int类型的检测方法,只有HOUGH_GRADIENT这一种;第四个参数用于检测圆心累加器图像的分辨率于输入的比的倒数;两个默认参数:第七个参数是检测两个圆心之间的最小距离: