曲率卷积核提取图像曲率

本文介绍了一种使用特定的3*3曲率卷积核进行图像曲率提取的方法,并提供了C++与Python实现代码。该方法通过结合开闭运算来增强图像轮廓,最后应用卷积核提取曲率特征。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

曲率卷积核提取图像曲率


author@jason
http://blog.youkuaiyun.com/lql0716


1 曲率卷积核

-1/165/16-1/16
5/16-15/16
-1/165/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 <opencv2/opencv.hpp>

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)


  • 相关文章

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI人工智能科学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值