图像实验2

您所在的位置:网站首页 对图像均衡化处理 图像实验2

图像实验2

2023-07-20 15:30| 来源: 网络整理| 查看: 265

一、实验目的

掌握对图像直方图进行操作,实现图像的直方图均衡算法。 1、掌握求灰度图像归一化直方图方法 2、掌握灰度图像的直方图均衡算法 3、掌握对彩色图像进行直方图均衡的算法

二、实验内容

1、计算灰度图像的归一化直方图。 具体内容:利用 OpenCV 对图像像素进行操作,计算归一化直方图.并在 窗口中以图形的方式显示出来 2、灰度图像直方图均衡处理 具体内容:通过计算归一化直方图,设计算法实现直方图均衡化处理。 3、彩色图像直方图均衡处理 具体内容: 在灰度图像直方图均衡处理的基础上实现彩色直方图均衡处理。

三、实验完成情况 1、计算灰度图像的归一化直方图 核心代码 //计算归一化直方图 static Mat getHistogram(Mat img, double& min_value, double& max_value) { //图像数量 int nimage = 1; //通道标号序列,这里由于只需要灰度,因此队列只有一通道 int channels[] = { 0 }; //可选,如果不为空,即8-bit且与图像同尺寸的矩阵序列,此时第i个图像被mask[i]覆盖的区域才会参与统计,此处取默认空值 Mat mask; //输出直方图矩阵 Mat hist; //直方图的维度/通道数,如取4则代表(a,b,c,d)为在第一个通道上为a,第二个通道上为b,第三个通道上为c,第四个通道上为d的像素统计数 //此处只有灰度,因此只取1即可 int dims = 1; //histSize[i]代表第i个维度/通道上直方图的直方条数量,这里采用256每个阶数占用一个直方条 const int histSize[] = { 256 }; //与uniform标记有关,如果uniform为true,则range[i]两个值代表直方图的第i个维度上每个直方条的上下限,如果为false则range[i]的histSize[i]+1个值分别代表每个直方条的上下限 float hrange[] = { 0,255 }; const float* range[] = { hrange }; //代表直方条是否均匀等宽,true为等宽,false为不等 bool uniform = true; //标记直方图重新分配时是否清零,如果为否则可以进行累加 bool accumulate = false; //计算直方图 calcHist(&img, nimage, channels, mask, hist, dims, histSize, range, uniform, accumulate); //计算灰度最小和最大值 minMaxLoc(hist, &min_value, &max_value); //直方图画布,采用8bit位深,无符号整型以及3通道图片进行绘制 Mat target = Mat::zeros(Size(256, 300), CV_8UC3); //绘制直方图 for (int top, i = 0; i < 256; i++) { //计算直方条上界 top = cvRound(hist.at(i)/max_value*256); //绘制直方条 line(target, Point(i, target.rows - 1), Point(i, target.rows - 1 - top), Scalar::all(255)); } return target; } 实现截图

2、灰度图像直方图均衡处理 核心代码 //直方图均衡化处理 void channelEqualization(Mat &layer) { //均衡化 equalizeHist(layer, layer); } //均衡化手动函数 void myChannelEqualization(Mat & layer) { //总像素数 double sum = (double)img.rows * (double)img.cols; //各灰度总和 double cnt[256] = { 0 }; //均衡化像素数 uchar equal[256]; //统计各灰度值总数 for (int i = 0; i < layer.rows; i++) { uchar* ptr = layer.ptr(i); for (int j = 0; j < layer.cols; j++) { cnt[ptr[j]]++; } } //获取均衡化像素密度 cnt[0] /= sum; for (int i = 1; i < 256; i++) cnt[i] = cnt[i] / sum + cnt[i - 1]; //获取均衡化后灰度值 for (int i = 0; i < 256; i++) equal[i] = (uchar)(255 * cnt[i]); //替换均衡化灰度 for (int i = 0; i < layer.rows; i++) { uchar* ptr = layer.ptr(i); for (int j = 0; j < layer.cols; j++) { ptr[j] = equal[ptr[j]]; } } } //均衡化预处理 Mat handleEqualization(bool hsv, bool my) { Mat target = img.clone(); //彩色图像处理 if (color) { Mat result; vector channels; //HSV方式处理 if (hsv) { //转换为HSV图像 cvtColor(target, target, COLOR_BGR2HSV); //分离通道 split(target, channels); //处理亮度层,不影响色彩 my ? myChannelEqualization(channels[2]) : channelEqualization(channels[2]); //将亮度层组合 merge(channels, result); //转换回RGB图像 cvtColor(result, result, COLOR_HSV2BGR); } //RGB方式处理 else { //分离RGB通道 split(target, channels); //每个通道单独均衡化处理 for (int i = 0; i < channels.size(); i++) my ? myChannelEqualization(channels[i]) : channelEqualization(channels[i]); //将图层组合 merge(channels, result); } return result; } //灰阶图像处理 else { my ? myChannelEqualization(target) : channelEqualization(target); return target; } } 实现截图

3、彩色图像直方图均衡处理 核心代码

同灰度均衡处理代码,参数color为true即可。

实现截图

RGB均衡处理 RGB均衡直方图 HSV均衡处理 HSV均衡直方图

四、实验中的问题 OpenCV中关于计算直方图的函数calcHist参数较多切较难理解。 灰度和彩色均衡化处理的过程有所区别,主要为通道数的不同,起初统一处理时出现均衡化失败或者只有单通道均衡化的问题。 五、实验结果 源码 lab2.cpp #include #include #include using namespace std; using namespace cv; const static std::string path = "F:\\Documents\\高级图像处理\\Image\\"; //图片路径组合 string getFullPath(string name) { return path + name; } Mat show_h(Mat img) { int channels = 0; MatND dstHist; //设定像素取值范围 int hisSize[] = { 256 }; float midRanges[] = { 0,255 }; const float* ranges[] = { midRanges }; //计算直方图 calcHist(&img, 1, &channels, Mat(), dstHist, 1, hisSize, ranges, true, false); Mat drawImage = Mat::zeros(Size(256, 256), CV_8UC3); double MaxValue; minMaxLoc(dstHist, 0, &MaxValue, 0, 0);//图像最小最大值 for (int i = 0; i < 256; i++) { int value = cvRound((float)dstHist.at(i) * 256 * 0.9 / MaxValue);//四舍五入 //在直方图画布上画出直方图 line(drawImage, Point(i, drawImage.rows - 1), Point(i, drawImage.rows - 1 - value), Scalar(255, 255, 255)); } return drawImage; } //打开图片显示窗口 void openWindows(string win_name, Mat img, int x = 500, int y = 500) { //窗口命名,指定大小,生成位置 namedWindow(win_name, WINDOW_AUTOSIZE); moveWindow(win_name, x, y); //生成窗口显示图片 imshow(win_name, img); //等待键入 waitKey(); //关闭窗口 destroyWindow(win_name); } //统一数字输入函数 templateT inputNumber(string desc) { system("cls"); T input; cout > input; cout img.channels() != 1; } //归一化直方图 void show() { openWindows("直方图", Histogram::getHistogram(img, min_value, max_value)); } //直方图均衡化处理 void equalization(bool hsv = false,bool my = false) { Mat equal_img = handleEqualization(hsv,my); openWindows("原图", img); openWindows("均衡化图像", equal_img); openWindows("均衡化直方图", Histogram::getHistogram(equal_img, min_value, max_value)); } }; int main() { string name = "test.jpg"; //灰度图像 GrayImage gray_img(name); //灰阶直方图 Histogram ghist(gray_img); //归一化直方图 ghist.show(); //均衡化 ghist.equalization(); //彩色图像 ColorImage color_img(name); //彩色直方图 Histogram chist(color_img); //均衡化 chist.equalization(false); return 0; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3