數組圖像處理:直方圖規定化

#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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章