【opencv】图像卷积cv::filter2D()以及c++代码实例

自己写图像锐化函数:

#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>

using namespace std;
using namespace cv;

void Sharpen(const Mat& myImage, Mat& Result);

int main()
{
    Mat srcImage = imread("1.png");

    //判断图像是否加载成功
    if(srcImage.data)
        cout << "图像加载成功!" << endl << endl;
    else
    {
        cout << "图像加载失败!" << endl << endl;
        return -1;
    }
    namedWindow("srcImage", WINDOW_AUTOSIZE);
    imshow("srcImage", srcImage);

    Mat dstImage;
    dstImage.create(srcImage.size(), srcImage.type());
    Sharpen(srcImage, dstImage);
    namedWindow("dstImage",WINDOW_AUTOSIZE);
    imshow("dstImage",dstImage);

    waitKey(0);

    return 0;
}

void Sharpen(const Mat& myImage, Mat& Result)
{
    CV_Assert(myImage.depth() == CV_8U);        //判断函数CV_Assert
    const int nChannels = myImage.channels();

    for(int j = 1; j < myImage.rows - 1; ++j)
    {
        const uchar* precious = myImage.ptr<uchar>(j - 1);      //当前像素上一行指针
        const uchar* current = myImage.ptr<uchar>(j);           //当前像素行指针
        const uchar* next = myImage.ptr<uchar>(j + 1);          //当前像素下一行指针

        uchar* output = Result.ptr<uchar>(j);

        //利用公式和上下左右四个像素对当前像素值进行处理
        for(int i = nChannels; i < nChannels * (myImage.cols - 1); ++i)
        {
             // 0, -1 ,0;     -1, 5, -1;    0, -1, 0;
            *output++ = saturate_cast<uchar>(5 * current[i] 
                      -current[i-nChannels]-current[i+nChannels]
                      -precious[i]-next[i]);
        }
    }
    Result.row(0).setTo(Scalar(0));                 //设置第一行所有元素值为0
    Result.row(Result.rows-1).setTo(Scalar(0));     //设置最后一行所有元素值为0
    Result.col(0).setTo(Scalar(0));                 //设置第一列所有元素值为0
    Result.col(Result.cols-1).setTo(Scalar(0));     //设置最后一列所有元素值为0
}

上面代码是以卷积核为 [ 0 − 1 0 − 1 5 − 1 0 − 1 0 ] \begin{bmatrix} 0&-1&0\\ -1&5&-1 \\ 0&-1&0 \end{bmatrix} ⎣⎡​0−10​−15−1​0−10​⎦⎤​为例的锐化,结果图就是轻微的锐化,这里不做展示。


图像卷积运算API函数: cv::filter2D()

举例: 直接使用边缘检测的拉普拉斯算子API函数,与自己定义拉普拉斯算子核使用cv::filter2D()的效果对比:

#include <iostream>
#include <string>
#include <vector>

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
// g++ test.cpp `pkg-config opencv --libs --cflags` -std=c++11 -pthread -o test

using namespace std;
using namespace cv;

const int Kenel_s = 3;  //卷积核大小

int main() {
  //读入图片
  Mat src, dst, dst_L;
  src = imread("1.png", 0);

  // copyMakeBorder(src, src, Kenel_s - 1, Kenel_s - 1, Kenel_s - 1, Kenel_s -
  // 1, BORDER_CONSTANT, Scalar(0));  //填充图像
  imshow("Image of src", src);
  dst = src.clone();
  cv::Laplacian(dst, dst, dst.depth());
  imshow("Image of Laplacian API", dst);

  // cv::Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
  // cv::Mat kernel = (Mat_<char>(3, 3) << -1, -1, -1, -1, 8, -1, -1, -1, -1);
  cv::Mat kernel = (Mat_<char>(3, 3) << 1, 1, 1, 1, -8, 1, 1, 1, 1);
  cv::filter2D(src, src, CV_8UC3, kernel);
  imshow("Image of Laplacian 2", src);
  while (waitKey(0) != 'q') {
  };
  return 0;
}

origin:
【opencv】图像卷积cv::filter2D()以及c++代码实例

API:
【opencv】图像卷积cv::filter2D()以及c++代码实例

cv::filter2D():
【opencv】图像卷积cv::filter2D()以及c++代码实例

上一篇:opencv-convertTo转换数据格式


下一篇:opencv(python) 图像分割