具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来
步骤:
(1)初始化一个256大小的数组,存放图像中每级灰度值的像素点的个数
(2)遍历整张图像
(3)归一化数组
具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。
步骤:
(1)读取该像素点的灰度值
(2)计算其在归一化直方图中的累加概率
(3)累加概率乘以255,并四舍五入
具体内容: 在灰度图像直方图均衡处理的基础上实现彩色直方图均衡处理
步骤:
(1)读取该像素点的三通道灰度值
(2)计算其在归一化直方图中的累加概率
(3)累加概率乘以255,并四舍五入
实验环境:
(1)OpenCV3.4.3
(2)Ubuntu16.04
(3)VS Code
(4)C++
#include
#include
#include
#include
#include
class Experiment2 {
public:
Experiment2(std::vector path){
for(int i = 0; i < path.size(); i++){
original_color_image.push_back(cv::imread(path[i]));
original_gray_image.push_back(color2Gray(original_color_image[i]));
}
}
// 0.1、彩色图像转灰度图像
cv::Mat color2Gray(cv::Mat src_image){
//创建与原图同类型和同大小的矩阵
cv::Mat gray_image(src_image.rows, src_image.cols, CV_8UC1);
if(src_image.channels()!=1){
for(int i = 0; i < src_image.rows; i++)
for(int j = 0; j < src_image.cols; j++)
gray_image.at(i, j) = (src_image.at(i, j)[0] + src_image.at(i, j)[1] + src_image.at(i, j)[2]) / 3;
}
else
gray_image = src_image.clone();
return gray_image;
}
// 2.1、计算灰度图像的归一化直方图
void computerGrayHistogram(int pic_id, int opt=1){
std::vector hist(256,0);
cv::Mat image = (opt > 0) ? original_gray_image[pic_id] : gray_image_equalization[pic_id];
float nums = image.rows * image.cols;
float max = 0;
for(int i = 0; i < image.rows; i++)
for(int j = 0; j < image.cols; j++)
hist[image.at(i, j)]++;
for(int i=0; i < 256; i++){
hist[i] = hist[i] / nums;
if(hist[i] > max)
max = hist[i];
}
if(opt)
gray_hist.push_back(hist);
else
gray_hist_equalization.push_back(hist);
drawGrayHist(max, pic_id, opt);
}
// 2.2、绘制归一化直方图
void drawGrayHist(float maxValue, int pic_id, int opt=1){
int scale = 20000;
int hist_h = scale * maxValue, hist_w = 257;
std::vector hist = (opt > 0) ? gray_hist[pic_id] : gray_hist_equalization[pic_id];
// 画图底色
cv::Mat image_hist = cv::Mat::zeros(hist_h, hist_w, CV_8U);
// 画出直方图
for (int i = 0; i < 256; i++){
float binValue = hist[i];
int realValue = cv::saturate_cast(binValue * scale);
cv::rectangle(image_hist,
cv::Point(i, hist_h - realValue),
cv::Point(i + 1, hist_h),
cv::Scalar(255));
}
if(opt)
gray_image_hist.push_back(image_hist);
else
gray_image_hist_equalization.push_back(image_hist);
}
// 3、灰度图像直方图均衡处理
void grayEqualization(int pic_id){
cv::Mat image_equalization = cv::Mat::zeros(original_gray_image[pic_id].size(), original_gray_image[pic_id].type());
for(int i = 0; i < original_gray_image[pic_id].rows; i++)
for(int j = 0; j < original_gray_image[pic_id].cols; j++){
int k = original_gray_image[pic_id].at(i, j);
float sum = 0;
for(int m = 0; m <= k; m++)
sum += gray_hist[pic_id][m];
image_equalization.at(i, j) = sum * 255 + 0.5;
}
gray_image_equalization.push_back(image_equalization);
}
// 4.1、彩色图像直方图均衡处理
void colorEqualization(int pic_id){
cv::Mat image_equalization = cv::Mat::zeros(original_color_image[pic_id].size(), original_color_image[pic_id].type());
for(int i = 0; i < original_color_image[pic_id].rows; i++)
for(int j = 0; j < original_color_image[pic_id].cols; j++)
for(int n = 0; n < 3; n++){
int k = original_color_image[pic_id].at(i, j)[n];
float sum = 0;
for(int m = 0; m <= k; m++)
sum += color_hist[pic_id][n][m];
image_equalization.at(i, j)[n] = sum * 255 + 0.5;
}
color_image_equalization.push_back(image_equalization);
}
// 4.2、计算彩色图像的归一化直方图
void computerColorHistogram(int pic_id){
std::vector > hist(3, std::vector(256));
int nums = original_color_image[pic_id].rows * original_color_image[pic_id].cols;
for(int i = 0; i < original_color_image[pic_id].rows; i++)
for(int j = 0; j < original_color_image[pic_id].cols; j++){
hist[0][original_color_image[pic_id].at(i, j)[0]]++;
hist[1][original_color_image[pic_id].at(i, j)[1]]++;
hist[2][original_color_image[pic_id].at(i, j)[2]]++;
}
for(int i=0; i < 256; i++){
hist[0][i] = hist[0][i] / nums;
hist[1][i] = hist[1][i] / nums;
hist[2][i] = hist[2][i] / nums;
}
color_hist.push_back(hist);
}
// 5 显示 灰度均衡化 与 灰度直方图
void test_GrayEqualizationAndHistogram(){
for(int i = 0; i < original_gray_image.size(); i++){
computerGrayHistogram(i);
grayEqualization(i);
std::cout<< "灰度图像: 当前已经均衡化第" << i + 1 << "张图像\n";
}
// 显示结果
cv::imshow(" 原始灰度图像", original_gray_image[0]);
cv::waitKey(0);
for(int i = 0; i < original_gray_image.size(); i++){
cv::imshow("原始图像的灰度直方图:", gray_image_hist[i]);
cv::waitKey(0);
cv::imshow("均衡化后的灰度图像:", gray_image_equalization[i]);
cv::waitKey(0);
}
std::cout<< "\n";
}
// 6 显示 彩色均衡化
void test_ColorEqualizationAndHistogram(){
for(int i = 0; i < original_color_image.size(); i++){
computerColorHistogram(i);
colorEqualization(i);
std::cout<< "彩色图像: 当前已经均衡化第" << i + 1 << "张图像\n";
}
// 显示结果
cv::imshow("原始图像", original_color_image[0]);
cv::waitKey(0);
for(int i = 0; i < original_color_image.size(); i++){
cv::imshow("均衡化后---彩色图像:", color_image_equalization[i]);
cv::waitKey(0);
}
}
private:
std::vector color_info;
std::vector gray_info;
// 原始图像
std::vector original_color_image;
std::vector original_gray_image;
// 均衡化后的图像
std::vector color_image_equalization;
std::vector gray_image_equalization;
// 画出来的灰度直方图
std::vector gray_image_hist;
std::vector > color_image_hist;
std::vector gray_image_hist_equalization;
std::vector > color_image_hist_equalization;
// 灰度图像的灰度分布 (图像名,每级灰度的个数)
std::vector > gray_hist;
std::vector > gray_hist_equalization;
// 彩色图像的灰度分布(图像名,通道,每级灰度的个数)
std::vector > > color_hist;
std::vector > > color_hist_equalization;
};
int main(){
std::vector path;
path.push_back("/home/lyd/image_process/pic/lena.jpg");
Experiment2 a(path);
a.test_GrayEqualizationAndHistogram();
a.test_ColorEqualizationAndHistogram();
return 1;
}