这里介绍了两种方法进行图像的锐化, 即卷积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; }