曲率卷积核提取图像曲率
阅读原文时间:2021年04月21日阅读:1

曲率卷积核提取图像曲率


author@jason
http://blog.csdn.net/lql0716


1 曲率卷积核

-1/16

5/16

-1/16

5/16

-1

5/16

-1/16

5/16

-1/16

  • 利用该方法提取图像的曲率,可以和Sobel算子、Canny算法做对比,针对不同的需求,采用不同的算法。

2 曲率卷积提取曲率代码

2.1 C++代码

2.1.1 函数void convolution(cv::Mat img, cv::Mat& dst)

  • opencv2.4.13

  • 计算步骤:

    1. 开运算(先腐蚀后膨胀)
    2. 闭运算(先膨胀后腐蚀)
    3. 曲率卷积

    注:先开后闭,可以使得图像的轮廓更加清晰

    void convolution(cv::Mat img, cv::Mat& dst)
    {
    cv::Mat img_2, gray_1, gray_2, out, out2, out3, out4; //定义图像

    cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(3,3));  ///腐蚀膨胀操作的卷积核
    //开运算,先腐蚀后膨胀
    erode(img, out, element);  //腐蚀操作
    dilate(out, out2, element);  //膨胀操作
    //闭运算,先膨胀后腐蚀
    dilate(out2, out3, element);  //膨胀操作
    erode(out3, out4, element);  //腐蚀操作
    
    if((int)out4.channels() != 1){
        cv::copyMakeBorder(out4, img_2, 1, 1, 1, 1, cv::BORDER_DEFAULT, cv::Scalar(0,0,0));  //扩展图像边缘的函数(输入图像,输出图像,上,下,左,右,0,颜色),上下左右为扩展像素数
        cout<<img_2.size() <<endl;
        cv::cvtColor(out4, gray_1, cv::COLOR_BGR2GRAY);  //转换为灰度图
        cv::cvtColor(img_2, gray_2, cv::COLOR_BGR2GRAY);  //转换为灰度图
    }else{
        cv::copyMakeBorder(out4, img_2, 1, 1, 1, 1, cv::BORDER_DEFAULT, 0);  //扩展图像边缘的函数(输入图像,输出图像,上,下,左,右,0,颜色),上下左右为扩展像素数
        out4.copyTo(gray_1);  //复制图像gray_1到out4
        img_2.copyTo(gray_2);
    }
    
    gray_1.copyTo(dst);
    
    //对图像进行卷积操作
    for(int i = 1; i < gray_2.rows-1; i++ )
    {
        for(int j = 1; j < gray_2.cols-1; j++)
        {
            dst.at<uchar>(i-1,j-1) = ( - (int)gray_2.at<uchar>(i-1, j-1) + 5 * (int)(gray_2.at<uchar>(i-1, j))  - (int)(gray_2.at<uchar>(i-1, j+1)) \
                    + 5 * (int)(gray_2.at<uchar>(i, j-1)) - (int)(gray_2.at<uchar>(i,j)) * 16 + 5 * (int)(gray_2.at<uchar>(i, j+1)) \
                    - (int)(gray_2.at<uchar>(i+1, j-1)) + 5 * (int)(gray_2.at<uchar>(i+1, j)) - (int)(gray_2.at<uchar>(i+1, j+1))  ) / 16;
        }
    }

    }

2.1.2 完整示例代码

  • opencv2.4.13

    #include

    using namespace cv;
    using namespace std;

    void convolution(cv::Mat img, cv::Mat& dst)
    {
    cv::Mat img_2, gray_1, gray_2, out, out2, out3, out4;

    cv::Mat element = getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
    //开运算,先腐蚀后膨胀
    erode(img, out, element);  //腐蚀操作
    dilate(out, out2, element);  //膨胀操作
    //闭运算,先膨胀后腐蚀
    dilate(out2, out3, element);  //膨胀操作
    erode(out3, out4, element);  //腐蚀操作
    
    if ((int)out4.channels() != 1){
        cv::copyMakeBorder(out4, img_2, 1, 1, 1, 1, cv::BORDER_DEFAULT, cv::Scalar(0, 0, 0));  //扩展图像边缘的函数(输入图像,输出图像,上,下,左,右,0,颜色),上下左右为扩展像素数
        cout << img_2.size() << endl;
        cv::cvtColor(out4, gray_1, cv::COLOR_BGR2GRAY);
        cv::cvtColor(img_2, gray_2, cv::COLOR_BGR2GRAY);
    }
    else{
        cv::copyMakeBorder(out4, img_2, 1, 1, 1, 1, cv::BORDER_DEFAULT, 0);
        out4.copyTo(gray_1);
        img_2.copyTo(gray_2);
    }
    
    gray_1.copyTo(dst);
    
    for (int i = 1; i < gray_2.rows - 1; i++)
    {
        for (int j = 1; j < gray_2.cols - 1; j++)
        {
            dst.at<uchar>(i - 1, j - 1) = (-(int)gray_2.at<uchar>(i - 1, j - 1) + 5 * (int)(gray_2.at<uchar>(i - 1, j)) - (int)(gray_2.at<uchar>(i - 1, j + 1)) \
                + 5 * (int)(gray_2.at<uchar>(i, j - 1)) - (int)(gray_2.at<uchar>(i, j)) * 16 + 5 * (int)(gray_2.at<uchar>(i, j + 1)) \
                - (int)(gray_2.at<uchar>(i + 1, j - 1)) + 5 * (int)(gray_2.at<uchar>(i + 1, j)) - (int)(gray_2.at<uchar>(i + 1, j + 1))) / 16;
        }
    }

    }

    int main(){
    string path = "D:/photo/02.jpg";
    cv::Mat img, imgGray, dst, dstGray;
    img = cv::imread(path);

    convolution(img, dstGray);
    
    cv::namedWindow("dstGray", cv::WINDOW_NORMAL);
    cv::imshow("dstGray", dstGray);
    cv::waitKey(0);
    
    return 0;

    }

  • 原图:

  • 效果图:

2.2 python代码

2.1.1 函数convolution(img)

  • opencv2.4.13

  • 计算步骤:

    1. 开运算(先腐蚀后膨胀)
    2. 闭运算(先膨胀后腐蚀)
    3. 曲率卷积

    注:先开后闭,可以使得图像的轮廓更加清晰

    #曲率函数
    def convolution(img):

    kernel = (3,3)  #腐蚀膨胀的核
    #开运算,先腐蚀后膨胀
    img2 = cv2.erode(img, kernel)  #腐蚀操作
    img3 = cv2.dilate(img2, kernel)  #膨胀操作
    #闭运算,先膨胀后腐蚀
    img4 = cv2.dilate(img3, kernel)  #膨胀操作
    img5 = cv2.erode(img4, kernel)  #腐蚀操作
    a = img5.shape[0]  #获取图像的行数
    b = img5.shape[1]  #获取图像的列数
    c = img5.shape[2]  #获取图像的通道数
    
    #如果为RGB图像,则转换为灰度图
    if c != 1:
        img6 = cv2.copyMakeBorder(img5, 1, 1, 1, 1, cv2.BORDER_DEFAULT, (0, 0, 0))
        gray5 = cv2.cvtColor(img5, cv2.COLOR_RGB2GRAY)
        gray6 = cv2.cvtColor(img6, cv2.COLOR_RGB2GRAY)
    else:
        img6 = cv2.copyMakeBorder(img5, 1, 1, 1, 1, cv2.BORDER_DEFAULT, 0)
        gray5 = img5
        gray6 = img6
    a2 = gray6.shape[0]
    b2 = gray6.shape[1]
    dst = gray5
    
    #进行曲率提取操作
    for i in range(1, a2-1):
        for j in range(1, b2-1):
            dst[i-1,j-1] = (-gray6[i-1,j-1] + 5*gray6[i-1,j] - gray6[i-1,j+1] + 5*gray6[i,j-1] - 16*gray6[i,j] + 5*gray6[i,j+1] - gray6[i+1,j-1] + 5*gray6[i+1,j] - gray6[i+1,j+1]) / 16
    return dst

2.1.2 完整版代码

  • opencv2.4.13

    -- coding: utf-8 --

    """
    Created on Sun Mar 26 12:22:02 2017

    @author: lql0716
    """

    import cv2

    #曲率函数
    def convolution(img):

    kernel = (3,3)  #腐蚀膨胀的核
    #开运算,先腐蚀后膨胀
    img2 = cv2.erode(img, kernel)  #腐蚀操作
    img3 = cv2.dilate(img2, kernel)  #膨胀操作
    #闭运算,先膨胀后腐蚀
    img4 = cv2.dilate(img3, kernel)  #膨胀操作
    img5 = cv2.erode(img4, kernel)  #腐蚀操作
    a = img5.shape[0]  #获取图像的行数
    b = img5.shape[1]  #获取图像的列数
    c = img5.shape[2]  #获取图像的通道数
    
    #如果为RGB图像,则转换为灰度图
    if c != 1:
        img6 = cv2.copyMakeBorder(img5, 1, 1, 1, 1, cv2.BORDER_DEFAULT, (0, 0, 0))
        gray5 = cv2.cvtColor(img5, cv2.COLOR_RGB2GRAY)
        gray6 = cv2.cvtColor(img6, cv2.COLOR_RGB2GRAY)
    else:
        img6 = cv2.copyMakeBorder(img5, 1, 1, 1, 1, cv2.BORDER_DEFAULT, 0)
        gray5 = img5
        gray6 = img6
    a2 = gray6.shape[0]
    b2 = gray6.shape[1]
    dst = gray5
    
    #进行曲率提取操作
    for i in range(1, a2-1):
        for j in range(1, b2-1):
            dst[i-1,j-1] = (-gray6[i-1,j-1] + 5*gray6[i-1,j] - gray6[i-1,j+1] + 5*gray6[i,j-1] - 16*gray6[i,j] + 5*gray6[i,j+1] - gray6[i+1,j-1] + 5*gray6[i+1,j] - gray6[i+1,j+1]) / 16
    return dst

    #主代码函数
    img = cv2.imread('D:/photo/04.jpg')
    dst = convolution(img)
    cv2.namedWindow('img', cv2.WINDOW_NORMAL)
    cv2.imshow('img',dst)
    cv2.waitKey(0)

    cv2.imwrite('D:/photo/04_2python.jpg', dst)

  • 原图:

  • 效果图:

  • 对于C++版和Python版的效果图,设置的参数不一致,效果图也不一致。

  • 图像曲率处理的相关文章:

    如何计算图像的曲率?
    基于曲率的图像处理


  • 相关文章

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器