代码
hsi_f=rgb2hsv(f); %转换成HSI彩色空间
H=hsi_f(:,:,1); %色度分量
S=hsi_f(:,:,2); %饱和度分量
I=hsi_f(:,:,3); %亮度分量
I_equ=histeq(I); %均衡化
hsi_f_equ=cat(3,H,S,I_equ); %整合
fI_equ=hsv2rgb(hsi_f_equ); %转换回RGB空间
subplot(131),imshow(f),title('原图')
subplot(132),imshow(fI_equ),title('RGB均衡化')
C=duibidu4(fI_equ);
fprintf('\nC=%f',C);
fprintf('\n');
%%%%%%%%%%%%%%%%%%%%%%计算对比度函数%%%%%%%%%%%%%%%%
%方法一:中心像素灰度值与周围4近邻像素灰度值之差的平方之和,除以以上平方项的个数。
function[cg] = duibidu4(f) %f为输入图像,cg为输出的对比度数值,是英文contrast gradient的首字母组合
[m,n] = size(f); %求原始图像的行数m和列数n
g = padarray(f,[1 1],'symmetric','both');%对原始图像进行扩展,比如50*50的图像,扩展后变成52*52的图像,
%扩展只是对原始图像的周边像素进行复制的方法进行
[r,c] = size(g); %求扩展后图像的行数r和列数c
g = double(g); %把扩展后图像转变成双精度浮点数
k = 0; %定义一数值k,初始值为0
for i=2:r-1
for j=2:c-1
k = k+(g(i,j-1)-g(i,j))^2+(g(i-1,j)-g(i,j))^2+(g(i,j+1)-g(i,j))^2+(g(i+1,j)-g(i,j))^2;
end
end
cg = k/(4*(m-2)*(n-2)+3*(2*(m-2)+2*(n-2))+4*2);%求原始图像对比度
end
计算后对比度只有0.0007,但是在RGB空间对比度就是60
不知道你这个问题是否已经解决, 如果还没有解决的话:代码:
rgb=imread('peppers.png');%读入图像
subplot(221),imshow(rgb);title('原始图像')
hsv=rgb2hsv(rgb); %颜色空间转换
H=hsv(:,:,1); % 色调
S=hsv(:,:,2); % 饱和度
V=hsv(:,:,3); % 亮度
subplot(221);imshow(rgb);
subplot(222);imshow(H);title('色调')
subplot(223);imshow(S);title('饱和度')
subplot(224);imshow(V);title('亮度')
根据提供的参考资料和代码,问题可能出在对比度计算的方式上。HSV空间和RGB空间的对比度计算方式不同,而在代码中只给出了RGB空间下的对比度计算方式。因此,需要重新计算HSV空间下的对比度,并修改代码来实现。
下面给出在HSV空间下计算对比度的步骤:
Mat hsv_image;
cv::cvtColor(image, hsv_image, COLOR_BGR2HSV);
vector<Mat> hsv_planes;
split(hsv_image, hsv_planes);
for(int i=0;i<3;i++)
{
equalizeHist(hsv_planes[i], hsv_planes[i]);
}
merge(hsv_planes, hsv_image);
cv::cvtColor(hsv_image, image, COLOR_HSV2BGR);
此处对比度计算采用阈值来实现,将像素值小于阈值的像素都设置为0,像素值大于阈值的像素都设置为255,然后计算像素值为255的像素所占比例即可。
int threshold_value = 128; // 阈值
int count = 0; // 统计像素值为255的像素个数
for(int i=0;i<image.rows;i++)
{
for(int j=0;j<image.cols;j++)
{
if(image.at<Vec3b>(i,j)[2] > threshold_value) // 只考虑图像的亮度通道
{
count++;
}
if(image.at<Vec3b>(i,j)[2] < threshold_value)
{
image.at<Vec3b>(i,j) = Vec3b(0,0,0); // 小于阈值的像素都设置为0
}
else
{
image.at<Vec3b>(i,j) = Vec3b(255,255,255); // 大于阈值的像素都设置为255
}
}
}
float contrast = (float)count / (image.rows * image.cols); // 计算对比度
修改后的代码如下所示:
#include "stdio.h"
#include<iostream>
#include<opencv2/opencv.hpp>
#include<iomanip>
#include<cmath>
#include<string>
using namespace std;
using namespace cv;
int main()
{
const int num = 157; //在D:\\test_picture\\%d.png中你要处理的图片数量
char fileName[50];
char windowName[50];
Mat image;
float rateyellow; //要计算的百分率
float ratered;
float rategrey;
float ratewhite;
float rateblack;
float hsv_contrast;
cout << "序号" << "\t" << "HSV对比度" << "\t" << "黄色区域占比" << "\t" << "红色区域占比" << "\t" << "灰色区域占比""\t" << "白色区域占比""\t" << "黑色占比" << endl;
for (int k = 1; k <= num; k++){
//sprintf读入指定路径下的图片序列
sprintf_s(fileName, "D:\\test_picture\\%d.png", k);
sprintf_s(windowName, "No%d", k);
//按照图像文件名读取
image = imread(fileName);
// 转换为HSV空间
Mat hsv_image;
cv::cvtColor(image, hsv_image, COLOR_BGR2HSV);
// 对H,S,V三通道分别执行直方图均衡化
vector<Mat> hsv_planes;
split(hsv_image, hsv_planes);
for(int i=0;i<3;i++)
{
equalizeHist(hsv_planes[i], hsv_planes[i]);
}
merge(hsv_planes, hsv_image);
// 将HSV空间图像转回BGR空间
cv::cvtColor(hsv_image, image, COLOR_HSV2BGR);
// 计算对比度
int threshold_value = 128; // 阈值
int count = 0; // 统计像素值为255的像素个数
for(int i=0;i<image.rows;i++)
{
for(int j=0;j<image.cols;j++)
{
if(image.at<Vec3b>(i,j)[2] > threshold_value) // 只考虑图像的亮度通道
{
count++;
}
if(image.at<Vec3b>(i,j)[2] < threshold_value)
{
image.at<Vec3b>(i,j) = Vec3b(0,0,0); // 小于阈值的像素都设置为0
}
else
{
image.at<Vec3b>(i,j) = Vec3b(255,255,255); // 大于阈值的像素都设置为255
}
}
}
hsv_contrast = (float)count / (image.rows * image.cols); // 计算HSV空间下的对比度
// 计算各颜色占比
int numOfyellow = 0;
int numOfred = 0;
int numOfgrey = 0;
int numOfwhite = 0;
int numOfblack = 0;
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j <image.cols; j++) //遍历图片的每一个像素点
{
if ((image.at<Vec3b>(i, j)[0] <= 120 && image.at<Vec3b>(i, j)[1] >= 170 && image.at<Vec3b>(i, j)[2] >= 230)
|| (image.at<Vec3b>(i, j)[0]>120 && image.at<Vec3b>(i, j)[0] <= 180 && image.at<Vec3b>(i, j)[1] >= 180 &&
image.at<Vec3b>(i, j)[2] >= 220)){//对该像素是否为黄色进行判断
numOfyellow++;
}
if (image.at<Vec3b>(i, j)[0] <= 60 && image.at<Vec3b>(i, j)[1] <= 60 && image.at<Vec3b>(i, j)[2] >= 200){//对该像素是否为红色色进行判断
numOfred++;
}
if (image.at<Vec3b>(i, j)[0] <= 220 && image.at<Vec3b>(i, j)[0] >= 60 && abs(image.at<Vec3b>(i, j)[0] - image.at<Vec3b>(i, j)[1]) <= 15 &&
abs(image.at<Vec3b>(i, j)[0] - image.at<Vec3b>(i, j)[2]) <= 15){//对该像素是否为灰色进行判断
numOfgrey++;
}
if (image.at<Vec3b>(i, j)[0] >= 235 && image.at<Vec3b>(i, j)[1] >= 235 && image.at<Vec3b>(i, j)[2] >= 235){//对该像素是否为白色进行判断
numOfwhite++;
}
if (image.at<Vec3b>(i, j)[0] <= 45 && image.at<Vec3b>(i, j)[1] <= 45 && image.at<Vec3b>(i, j)[2] <= 45){//对该像素是否为黑色进行判断
numOfblack++;
}
}
}
rateyellow = (float)numOfyellow / (float)(image.rows * image.cols);
ratered = (float)numOfred / (float)(image.rows * image.cols);
rategrey = (float)numOfgrey / (float)(image.rows * image.cols);
ratewhite = (float)numOfwhite / (float)(image.rows * image.cols);
rateblack = (float)numOfblack / (float)(image.rows * image.cols);
cout << "NO" << k << "\t";
cout << fixed << setprecision(4) << hsv_contrast << "\t";
cout << fixed << setprecision(4) << rateyellow << "\t" << "\t";
cout << fixed << setprecision(4) << ratered << "\t" << "\t";
cout << fixed << setprecision(4) << rategrey << "\t" << "\t";
cout << fixed << setprecision(4) << ratewhite << "\t" << "\t";
cout << fixed << setprecision(4) << rateblack << endl;
}
return 0;
}