图像预处理~对左右部分分别直方图均衡化

一般的直方图均衡化对于光照的处理难免会有些瑕疵,这里介绍一种改进的直方图均衡化方法:对图像左右部分分别直方图均衡化。

说明:以下的程序是关于我自己的项目:人脸识别 做的,分别对左右两部分脸进行直方图均衡化,最后,由于直方图均衡化会带来很多噪声,所以使用了双边滤波。


#include <iostream>
#include <vector>
#include "opencv2/opencv.hpp"
#include <list>
#include<math.h>
#include <opencv2/highgui/highgui_c.h>
using namespace cv;
using namespace std;

Mat double_equ(Mat faceImg)
{
	int w = faceImg.cols;
	int h = faceImg.rows;
	Mat wholeFace;
	equalizeHist(faceImg, wholeFace);//整均衡化
	int midX = w / 2;
	Mat leftSide = faceImg(Rect(0, 0, midX, h));//左脸区域
	Mat rightSide = faceImg(Rect(midX, 0, w - midX, h));//右脸区域
	equalizeHist(leftSide, leftSide);//左均衡化
	equalizeHist(rightSide, rightSide);//右均衡化
		for (int y = 0; y<h; y++) {//y为rows行
			for (int x = 0; x<w; x++) {//x为cols列
				int v;
				if (x < w / 4) {
					// 左边25%,仅使用左脸
					v = leftSide.at<uchar>(y, x);//读取某个坐标处的像素值
				}
				else if (x < w * 2 / 4) {
					//中-左25% 混合左边脸和整个人脸 
					int lv = leftSide.at<uchar>(y, x);//左
					int wv = wholeFace.at<uchar>(y, x);//整个

					float f = (x - w * 1 / 4) / (float)(w / 4);//当前位置在该1/4空间中所占的比例
					v = cvRound((1.0f - f) * lv + (f)* wv);
					//左边脸和整个人脸在混合时所占的比例不一样,越靠近中心位置,在混合时左手边的脸所占的比例减小
				}
				else if (x < w * 3 / 4) {
					// Mid-right 25%: 混合右脸和整个脸
					int rv = rightSide.at<uchar>(y, x - midX);
					int wv = wholeFace.at<uchar>(y, x);
					// Blend more of the right-side face as it moves
					// further right along the face.
					float f = (x - w * 2 / 4) / (float)(w / 4);//x为列采用渐进混合
					v = cvRound((1.0f - f) * wv + (f)* rv);
					//左边脸和整个人脸在混合时所占的比例不一样,越靠近中心位置,在混合时右手边的脸所占的比例减小
				}
				else {
					// Right 25%: just use the right face.
					v = rightSide.at<uchar>(y, x - midX);
				}
				faceImg.at<uchar>(y, x) = v;
			}// end x loop
		}//end y loop
		Mat filtered = Mat(faceImg.size(), CV_8U);
		bilateralFilter(faceImg, filtered, 0, 20.0, 2.0);//双边滤波

	return filtered;

}




你可能感兴趣的:(图像处理)