5.9-OpenCV学习(6)

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这一种;第四个参数用于检测圆心累加器图像的分辨率于输入的比的倒数;两个默认参数:第七个参数是检测两个圆心之间的最小距离:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值