持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第15天,点击查看活动详情
首先,需要了解一下什么是图像的对比度,我们看一张图像时经常会觉得有的图像清晰一些,而有的图像不是很清晰,这就引出了图像对比度的概念,图像对比度在一定程度上体现了图像亮暗的拉伸对比程度。
对于图像对比对的计算公式,表示如下,其中第二行的公式表示像素差,这个像素差可以是4邻域相邻,也可以是8邻域相邻.第三行公式表示的是相邻像素间的灰度差为delta 的像素分布概率。
下面通过一个例子进行说明,下面就表示一个3x3像素大小的图像矩阵,以四邻域为例子进行说明,图像的对比度如何计算。
1 3 5
2 4 4
5 7 4
C=[(1^2+2^2) + (1^2+(-2)^2)+2^2) + ((-1)^2+(-2)^2) + ((-1)^2+3^2+2^2) + ((-1)^2+3^2+(-2)^2+0^2) + (1^2+0^2+0^2) + ((-3)^2+2^2) + ((-3)^2+(-2)^2) + (0^2+3^2)]/24=3.08
对于上面的计算流程,以左上角的1来说,它的四邻域分别是上下左右四个方向,但是1的位置在最边上,因此只有下和右两个邻域,分别是2和3,将两个邻域分别与1做差,然后求平方值,就完成了一个计算,对上面所有的像素执行这样的操作将结果相加,然后除以总的计算数的个数,就得到了这个3x3区域的对比度。
以代码进行表示如下,代码是C++编写的,使用了opencv框架,代码我准备编译为动态链接库的形式提供给外部调用,因此在每个函数的前面加上了__declspec(dllexport) 。
// 这一句为调用头文件,因为新建项目的时候我选择的新建DLL项目,如果建的空项目,这个头文件可以不要
#include"pch.h"
#include<iostream>
#include <opencv2/opencv.hpp>
using namespace cv;
__declspec(dllexport) double contrast(Mat image)
{
Mat image_gray;
cv::cvtColor(image, image_gray, cv::COLOR_BGR2GRAY);
int m = image.rows;
int n = image.cols;
Mat image_ext;
cv::copyMakeBorder(image_gray, image_ext, 1, 1, 1, 1, cv::BORDER_REPLICATE);
int m1 = image_ext.rows;
int n1 = image_ext.cols;
double b = 0.0;
for (int i = 1; i < m1 - 1; i++)
{
for (int j = 1; j < n1 - 1; j++)
{
double xy = image_ext.at<uchar>(i, j);
double x1 = pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i, j + 1)), 2);
double x2 = pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i, j - 1)), 2);
double x3 = pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i + 1, j)), 2);
double x4 = pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i - 1, j)), 2);
b += ((pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i, j + 1)), 2)) + (pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i, j - 1)), 2))
+ (pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i + 1, j)), 2)) + (pow((image_ext.at<uchar>(i, j) - image_ext.at<uchar>(i - 1, j)), 2)));
}
}
double cg = b / (4 * (m - 2) * (n - 2) + 3 * (2 * (m - 2) + 2 * (n - 2)) + 2 * 4);
return cg;
}
__declspec(dllexport) double runfunction(cv::String filename)
{
Mat image = imread(filename);
double result = contrast(image);
return result;
}
对于上述程序,编译后会生成DLL和Lib文件,如下所示。
对链接库进行调用的实例代码如下
#include <iostream>
#include "detect.h"
using namespace std;
// 这个Dll5.lib是自己生成的DLL文件
#pragma comment(lib,"Dll5.lib")
int main()
{
SayHello();
double a = runfunction("D:\\VSWorkSpace\\Project11\\x64\\Debug\\bs.tiff");
cout << a;
return 0;
}
结果如下