自己写图像锐化函数:
#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−10−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:
API:
cv::filter2D():