Opencv(C++)-锐化操作- 1.ptr(row))(获得位置) 2.Saturate_cast(0-255范围裁剪) 3.Mat_(3, 3)(制作掩膜) 4.filter2D(进行卷积操作) 5.getTickerConut(获取当前时间 ) 6.cvGetTickFrequency(获得频率)

这里介绍了两种方法进行图像的锐化, 即卷积mask为 [0, -1, 0, -1, 5,  - 1, 0, -1, 0]

1.使用imread读取输入图片

方法1:

     1. 使用Src.cols * Src.channel() 循环每一列和通道数, 使用Src.rows获得行数 

     2.使用Mat::zeros(Src.size(), Src.type()) 构造输出Dst的零矩阵

     3. 循环rows, 使用Src.ptr<uchar>(row)获得每一行的输入位置信息,使用Dst.ptr<uchar>(row)获得每一行的输出位置信息

     4. 循环cols, 使得output = Saturate_cast<uchar>() 用来进行循环遍历 

方法2:

    1.使用Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5,  - 1, 0, -1, 0) 构造掩膜 

     2.使用filter2d(Src, Dst, Src.depth(), kernel) 来进行循环 

#include<opencv2/opencv.hpp>
#include<iostream>
#include<math.h>

using namespace cv; 

int main() {
    Mat Src, Dst; 
    Src = imread("D:/opencv c++/1.read_picture/1.read_picture/woman.jpg"); 
    if (!Src.data) {
        printf("读取图像失败"); 
        return -1; 
    }
    imshow("input picture", Src); 
    //waitKey(0); 
    //方法1 
    int cols = Src.cols * Src.channels(); //获得每一列的数据 
    int rows = Src.rows; 
    int offsex = Src.channels(); //获得起始的位置 
    Dst = Mat::zeros(Src.size(), Src.type()); 
    for (int row = 1; row < rows - 1; row++) {
        const uchar *current = Src.ptr<uchar>(row);  //获得当前位置的行
        const uchar *next = Src.ptr<uchar>(row + 1); 
        const uchar *previous = Src.ptr<uchar>(row - 1); 
        uchar *output = Dst.ptr<uchar>(row); //获得输出结果的每一行位置 
        for (int col = offsex; col < cols - 1; col++) { //循环每一列的每个通道 
            output[col] = saturate_cast<uchar>(5 * current[col] - (current[col - offsex] + current[col + offsex] + next[col] + previous[col]));
        }
    }

    double t = getTickCount(); 
    //使用opencv的掩膜进行操作 
    //方法二
    Mat kernel = (Mat_<char>(3, 3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
    filter2D(Src, Dst, Src.depth(), kernel); 
    double s = (getTickCount() - t) / cvGetTickFrequency(); 
    printf("所需时间是%f", s); 
    imshow("output image", Dst);
    waitKey(0);
    return 0; 
}