HSI圖像在直方圖均衡化時隻需處理I通道即可。
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
using namespace std;
Mat RGB2HSI(Mat src) {
int lenth = src.rows;
int width = src.cols;
Mat hsi(lenth, width, CV_64FC3);
for (int row = 0; row < lenth; row++)
{
for (int col = 0; col < width; col++)
{
double h, s, i, theta, num;
double b = (double)src.at<Vec3b>(row, col)[0] / 255;
double g = (double)src.at<Vec3b>(row, col)[1] / 255;
double r = (double)src.at<Vec3b>(row, col)[2] / 255;
double mi, mx;
if (r > g && r > b)
{
mx = r;
mi = min(g, b);
}
else
{
if (g > b)
{
mx = g;
mi = min(r, b);
}
else
{
mx = b;
mi = min(r, g);
}
}
num = (r - g) * (r - g) + (r - b) * (g - b);
theta = acos(((r - g + r - b)*0.5) / sqrt(num));
if (g >= b)
{
h = theta;
}
else
{
h = 2 * 3.14 - theta;
}
h = h / (2 * 3.14);
i = (r + g + b) / 3;
s = 1 - mi / i;
hsi.at<Vec3d>(row, col)[0] = h;
hsi.at<Vec3d>(row, col)[1] = s;
hsi.at<Vec3d>(row, col)[2] = i;
}
}
return hsi;
}
Mat equal(Mat src)
{
src.convertTo(src, CV_8UC3, 255.0);
Mat temp1, src2;
vector <Mat> channels;
split(src, channels);
//equalizeHist(channels[0], channels[0]);
//equalizeHist(channels[1], channels[1]);
equalizeHist(channels[2], channels[2]);
imshow("i equal", channels[2]);
merge(channels, temp1);
//imshow("iqual", temp1);
temp1.convertTo(temp1, CV_64FC3, 1 / 255.0);
return temp1;
}
Mat HSI2RGB(Mat src) {
int lenth = src.rows;
int width = src.cols;
Mat dst(lenth, width, CV_64FC3);
for (int x = 0; x < lenth; x++)
{
for (int y = 0; y <width; y++)
{
double h = src.at<Vec3d>(x, y)[0] * 2 * 3.14;//H
double s = src.at<Vec3d>(x, y)[1]; //S
double i = src.at<Vec3d>(x, y)[2]; //I
double r, g, b, num1, num2;
if (h >= 0 && h < (3.14 * 2 / 3))
{
num1 = s * cos(h);
num2 = cos(3.14 / 3 - h);
r = 3 * i * (1 + num1 / num2) / 3;
b = 3 * i * (1 - s) / 3;
g = 3 * i - (r + b);
}
else if (h >= (3.14 * 2 / 3) && h < (3.14 * 4 / 3))
{
num1 = s * cos(h - 2 * 3.14 / 3);
num2 = cos(3.14 - h);
r = 3 * i * (1 - s) / 3;
g = 3 * (1 + num1 / num2) / 3 * i;
b = 3 * i - (r + g);
}
else if (h >= (3.14 * 4 / 3) && h <= (3.14 * 2))
{
num1 = s * cos(h - 4 * 3.14 / 3);
num2 = cos(3.14 * 5 / 3 - h);
g = 3 * (1 - s) / 3 * i;
b = 3 * i * (1 + num1 / num2) / 3;
r = 3 * i - (g + b);
}
dst.at<Vec3d>(x, y)[0] = b;
dst.at<Vec3d>(x, y)[1] = g;
dst.at<Vec3d>(x, y)[2] = r;
}
}
return dst;
}
int main() {
Mat src = imread("pink.jpg");
if (src.empty())
{
return -1;
}
Mat dst, dst2, dst3;
dst = RGB2HSI(src);
dst2 = equal(dst);
dst3 = HSI2RGB(dst2);
imshow("src", src);
imshow("RGB2HSI", dst);
imshow("HSI2RGB", dst3);
waitKey(0);
return 0;
}