有效的图像清晰度评价函数是采用数字图像处理技术实现图像聚焦区域检测的关键,针对此类问题,首先使用灰度直方图均衡化和中值滤波对图像进行预处理,然后采用基于Sobel算子的TenenGrad评价函数在感兴趣区域ROI内进行检测评分(参考OpenCV 图像清晰度评价),其中ROI得分最高的区域即为聚焦区域。通过20张图片的处理,对其聚焦性能进行了测试,结果表明该算法可行。
其中ROI区域大小设置为图片大小的按比例缩小版,然后从图片左上角一直扫描至整个图像,筛选出得分最高的区域,绘制出来即可。以下依次是原图、预处理后图、最终结果图:
#include <highgui/highgui.hpp>
#include <imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
#define SIZES 4 //ROI大小设定
int main()
{
char filename[100];
char outfile[100];
for (int k = 1; k < 21; k++) //一共20张图片
{
sprintf(filename, "G:\\courseStudy\\opencv\\final term-project\\project-3\\%d.jpg", k);
Mat imageSource = imread(filename);
Mat imageGrey;
//图像预处理
cvtColor(imageSource, imageGrey, CV_RGB2GRAY);
equalizeHist(imageGrey, imageGrey);
medianBlur(imageGrey, imageGrey, 1);
Mat imageSobel;
Sobel(imageGrey, imageSobel, CV_16U, 1, 1);
double meanValue = 0.0;
double maxValue = meanValue;
int movCols = imageSource.cols / 20;
int movRows = imageSource.rows / 20;
Rect select;
for (int j = 0; (imageSource.rows / SIZES + j*movRows) <= (imageSource.rows); j++)
{
for (int i = 0; (imageSource.cols / SIZES + i*movCols) <= (imageSource.cols); i++)
{
Mat ROI = imageSobel(Range(0 + j*movRows, imageSource.rows / SIZES + j*movRows), Range(0 + i*movCols, imageSource.cols / SIZES + i*movCols));
if (double(mean(ROI)[0]) > maxValue)
{
maxValue = mean(ROI)[0];
select.x = i*movCols;
select.y = j*movRows;
select.width = imageSource.cols / SIZES;
select.height = imageSource.rows / SIZES;
}
}
}
cv::rectangle(imageSource, select, Scalar(0, 255, 0), 2);
imshow("result", imageSource);
sprintf(outfile, "G:\\courseStudy\\opencv\\final term-project\\project-3\\result%d.jpg", k);
imwrite(outfile, imageSource);
}
waitKey();
}