#include <iostream>
#include <cmath>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
void statistics(Mat &m, float b[256], float g[256], float r[256])
{
for (int i = 0; i < 256; i++)
b[i] = g[i] = r[i] = 0;
Mat_<Vec3b>::iterator it_begin = m.begin<Vec3b>();
Mat_<Vec3b>::iterator it_end = m.end<Vec3b>();
for (Mat_<Vec3b>::iterator it = it_begin; it != it_end; it++)
{
b[(*it)[0]] += 1;
g[(*it)[1]] += 1;
r[(*it)[2]] += 1;
}
float sum = m.rows * m.cols;
for (int i = 0; i < 256; i++)
{
b[i] /= sum;
g[i] /= sum;
r[i] /= sum;
}
}
//根據已給的bgr的直方圖分佈,對圖像work進行規定化。
void specification(Mat &work, Mat &result, float distribution_b[], float distribution_g[], float distribution_r[])
{
float b[256] = { 0 }, g[256] = { 0 }, r[256] = { 0 };
statistics(work, b, g, r);
//對數組b,g,r,distribution_b,distribution_g,distribution_r進行累積
for (int i = 1; i < 256; i++)
{
b[i] += b[i - 1];
g[i] += g[i - 1];
r[i] += r[i - 1];
distribution_b[i] += distribution_b[i - 1];
distribution_g[i] += distribution_g[i - 1];
distribution_r[i] += distribution_r[i - 1];
}
int map_b[256], map_g[256], map_r[256]; //規定化後的映射關係
for (int i = 0; i < 256; i++)
{
float diff_b = 666, diff_g = 666, diff_r = 666; //保存差的絕對值的最小值, 初始值只要大於1即可。
int index_b = -1, index_g = -1, index_r = -1; //當差的絕對值取得最小值時對應的索引
for (int j = 0; j < 256; j++)
{
float diff = abs(b[i] - distribution_b[j]);
if (diff < diff_b)
{
diff_b = diff;
index_b = j;
}
diff = abs(g[i] - distribution_g[j]);
if (diff < diff_g)
{
diff_g = diff;
index_g = j;
}
diff = abs(r[i] - distribution_r[j]);
if (diff < diff_r)
{
diff_r = diff;
index_r = j;
}
}
map_b[i] = index_b;
map_g[i] = index_g;
map_r[i] = index_r;
}
result = work.clone();
Mat_<Vec3b>::iterator it_begin = result.begin<Vec3b>();
Mat_<Vec3b>::iterator it_end = result.end<Vec3b>();
for (Mat_<Vec3b>::iterator it = it_begin; it != it_end; it++)
{
(*it)[0] = map_b[(*it)[0]];
(*it)[1] = map_g[(*it)[1]];
(*it)[2] = map_r[(*it)[2]];
}
}
int main()
{
Mat image = imread("f:\\圖片\\one.jpg"); //變換前圖像
Mat reference = imread("f:\\圖片\\horse.png"); //用於產生規定直方圖
float b[256] = { 0 }, g[256] = { 0 }, r[256] = { 0 };
statistics(reference, b, g, r);
Mat result = image.clone();
specification(image, result, b, g, r);
namedWindow("原圖像", 0);
resizeWindow("原圖像", 500, 500);
namedWindow("規定化後", 0);
resizeWindow("規定化後", 500, 500);
namedWindow("規定直方圖", 0);
resizeWindow("規定直方圖", 500, 500);
imshow("原圖像", image);
imshow("規定直方圖", reference);
imshow("規定化後", result);
waitKey(0);
return 0;
}
數組圖像處理:直方圖規定化
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.