图像增强
1.直方图统计与绘制
//直方图统计
vector<int> cal_hist(const Mat&src)
{
vector<int>histogram(256, 0);
//计算直方图
int pixelCount = src.cols*src.rows;
uchar *imageData = src.data;
for (int i = 0; i < pixelCount; ++i)
{
int gray = imageData[i];
histogram[gray]++;
}
return histogram;
}
opencv绘制直方图
void Draw_HistGram(Mat&src)
{
vector<int>HistGram;
Mat histimg;
HistGram = cal_hist(src);
int length = HistGram.size();
int max = 0;
for (int k = 0; k < length; k++)
{
//cout << HistGram[k] << endl;
if (HistGram[k] > max)
max = HistGram[k];
}
cout << "max=" << max << endl;
int h = length + 100;
int w = length + 50;
Mat hist_img = Mat::zeros(h, w, CV_8UC3);
hist_img = Scalar::all(255);
int i, j;
double height;
for (i = 0; i < length; i++)
{
j = i + 20;
height = (double)HistGram[i] / max * (h - 20);
rectangle(hist_img, Rect(j, hist_img.rows - height, 1, height), Scalar(158, 158, 58), 1);
}
namedWindow("histogram", WINDOW_NORMAL);
imshow("histogram", hist_img);
}
2.像素统计
//定义灰度特征结构体
struct pixel_statictical
{
double max=0;
double min=0;
double mean=0;
double ratio_0 = 0;
double ratio_255 = 0;
};
//灰度统计
void Distribution(const Mat&src,pixel_statictical&pixel)
{
double cols = src.cols;
double rows = src.rows;
float sum = 0;
double mean = 0;
double max = 0;
double min = 300;
vector<int>hist(256, 0);
hist = cal_hist(src);
//cout << hist[0] << " " << hist[255] << endl;
pixel.ratio_0 = hist[0] / cols / rows;
pixel.ratio_255 = hist[255] / cols / rows;
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
double p_ = src.at<uchar>(i, j);
//cout << pixel/255 << endl;
sum += p_;
if (p_ > max)
{
max = p_;
}
if (p_ < min)
{
min = p_;
}
}
}
pixel.mean = sum / cols / rows;
pixel.max = max;
pixel.min = min;
cout << "max = " << pixel.max << " min = " << pixel.min << " mean = " << pixel.mean ;
cout << " ratio_0 = " << pixel.ratio_0 << " ratio_255 = " << pixel.ratio_255 << endl;
}
3.自适应伽马变换
由局部自适应伽马变换更改,讲局部伽马比那换窗口去掉了,采用全局均值
void auto_Gamma_1(Mat &src, Mat &dst,int th)
{
Mat gray,gauss;
if (src.channels() == 3)
cvtColor(src, gray, COLOR_BGR2GRAY);
else
gray = src.clone();
int cols = gray.cols;
Mat mask = 255 - gray;
GaussianBlur(mask, gauss, Size(41, 41), BORDER_DEFAULT);
double mean = 0;
for (int k = 0; k < cols*rows; ++k)
{
mean += gauss.data[k];
}
mean = mean / (cols*rows);
cout << mean << endl;
Mat result = gray.clone();
for (int i = 0; i < rows; ++i)
{
for (int j = 0; j < cols; ++j)
{
double s = gray.at<uchar>(i, j);
double b = gauss.at<uchar>(i, j);
double a = (th - b)/ th;
double gamma = pow(2, a);
result.at<uchar>(i,j) = 255.*pow(s / 255., gamma);
}
}
//double mean = 0;
//for (int k = 0; k < cols*rows; ++k)
//{
// mean += gauss.data[k];
//}
//mean = mean / (cols*rows);
//uchar gray_table[256];
//for (int i = 0; i < 256; ++i)
//{
// double a = (th - mean) / th;
// double gamma = pow(2, a);
// gray_table[i] = 255.*pow(static_cast<double>(i) / 255., gamma);
//}
//Mat result = gray.clone();
//for (int k = 0; k < cols*rows; ++k)
//{
// result.data[k] = gray_table[gray.data[k]];
//}
dst = result.clone();
}
4.改进伽马变换
void auto_Gamma_2(Mat &src, Mat &dst)
{
int rows = src.rows;
int cols = src.cols;
double mean = 0;
for (int k = 0; k < cols*rows; ++k)
{
mean += src.data[k];
}
mean = mean / (cols*rows);
uchar gray_table[256];
double gamma = mean / 128;
cout << gamma << endl;
for (int i = 0; i < 256; ++i)
{
gray_table[i] = 255.*pow(static_cast<double>(i) / 255., gamma);
}
Mat result = Mat(src.size(), CV_8UC1);
for (int k = 0; k < cols*rows; ++k)
{
result.data[k] = gray_table[src.data[k]];
}
dst = result.clone();
}