// div must be a power of 2
int n= static_cast<int>(log(static_cast<double>(div))/log(2.0) + 0.5);
// mask used to round the pixel value
uchar mask= 0xFF<<n; // e.g. for div=16, mask= 0xF0
uchar div2 = div >> 1; // div2 = div/2
// get iterators
cv::Mat_<cv::Vec3b>::iterator it= image.begin<cv::Vec3b>();
cv::Mat_<cv::Vec3b>::iterator itend= image.end<cv::Vec3b>();
// scan all pixels
for ( ; it!= itend; ++it) {
// process each pixel ---------------------
(*it)[0]&= mask;
(*it)[0]+= div2;
(*it)[1]&= mask;
(*it)[1]+= div2;
(*it)[2]&= mask;
(*it)[2]+= div2;
// end of pixel processing ----------------
}
}
在图像处理中经常有这样的处理函数,它在计算每个像素的数值时,需要使用周边像素的值。 如果相邻像素在上一行或下一行,就需要同时扫描图像的多行。
我们将使用一个锐化图像的处理函数。它基于拉普拉斯算子。在图像处理领域有一个众所周知的结论:如果从图像中减去拉普拉斯算子部分,图像 的边缘就会放大,因而图像会变得更加尖锐。
实现思路:
图像扫描中使用了三个指针
一个表 示当前行、一个表示上面的行、一个表示下面的行
另外,因为在计算每一个像素时都需要访问 与它相邻的像素,所以有些像素的值是无法计算的,比如第一行、最后一行和第一列、最后一列 的像素。
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
void sharpen(const cv::Mat &image, cv::Mat &result) {
result.create(image.size(), image.type()); // allocate if necessary
int nchannels= image.channels();
for (int j= 1; j<image.rows-1; j++) { // for all rows (except first and last)
const uchar* previous= image.ptr<const uchar>(j-1); // previous row
const uchar* current= image.ptr<const uchar>(j); // current row
const uchar* next= image.ptr<const uchar>(j+1); // next row
uchar* output= result.ptr<uchar>(j); // output row
for (int i=nchannels; i<(image.cols-1)*nchannels; i++) {
// apply sharpening operator
*output++= cv::saturate_cast<uchar>(5*current[i]-current[i-nchannels]-current[i+nchannels]-previous[i]-next[i]);
}
}
// Set the unprocess pixels to 0
result.row(0).setTo(cv::Scalar(0));
result.row(result.rows-1).setTo(cv::Scalar(0));
result.col(0).setTo(cv::Scalar(0));
result.col(result.cols-1).setTo(cv::Scalar(0));
}
int main()
{
cv::Mat image= cv::imread("boldt.jpg");
if (!image.data)
return 0;
cv::Mat result;
double time= static_cast<double>(cv::getTickCount());
sharpen(image, result);
time= (static_cast<double>(cv::getTickCount())-time)/cv::getTickFrequency();
std::cout << "time= " << time << std::endl;
cv::namedWindow("Image");
cv::imshow("Image",result);
cv::waitKey();
return 0;
}
时间:time= 0.00339625
Linux公社的RSS地址:https://www.linuxidc.com/rssFeed.aspx