博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【数字图像处理】实验二 直方图均衡(vs2017+opencv)
阅读量:2355 次
发布时间:2019-05-10

本文共 4312 字,大约阅读时间需要 14 分钟。

文章目录

代码包:

一、实验原理

在这里插入图片描述

上述表达式, r k r_k rk表示输入的灰度级k, s k s_k sk表示对应输出的灰度级k, n j n_j nj表示输入图像中灰度级为K的像素个数。M和N分别是输入图像的长宽。L是灰度级。

二、设计思路

  • 上面的式子是对灰度图像处理的方法。但是我们一般处理的既有灰度图像也有彩色图像。所以如果是彩色图像我们要分别统计彩色图像R,G,B三者在各个灰度级上的像素数。然后进行处理。
  • 设计一个类如下:
#include 
#include
#include
#define LEAVE 256//灰度级using namespace cv;class Equalization {
public: //初始化各个私有成员。 Equalization(); //设置要处理的图片 void setImage(Mat &image_in ); //分别对图片的RGB值进行直方图统计 void statistic(); //对原图进行均衡处理 Mat queProcess();private: //三个私有变量分别统计channel 0, 1,2的灰度级的像素个数 int statistic_R[LEAVE]; int statistic_G[LEAVE]; int statistic_B[LEAVE]; //将要处理的图像 Mat image;};

三、实验过程

  • 下面需要注意的是数据类型的转换,如果只将const_num定义为double类型,而不管后面运算数的类型。编译器会直接拿int类型的数据去计算,得到的结果当然不一定是整数,但是编译器会直接把算得的值当作int来处理。就算你声明的const_num是double类型,也不管用。**所以在进行除运算之前要先将int类型强制转换为double类型。**就这句double const_num = (double)(LEAVE - 1) /(double) (this->image.cols*this->image.rows);
  • 还有一点是计算上面的 s k s_k sk的时候,结果是小数double类型,但我们最终需要的是int类型,所以要进行类型转换。但是直接强制类型转换会截取整数部分,不管小数部分的大小。而为了转换准确一点,我们最好采用四舍五入,就是给每个计算结果加上0.5,这样小数部分大于等于0.5的数,其整数就会被加一,然后进行强制类型转换,达到四舍五入的目的。
#include "Equalization.h"//初始化各个私有成员。Equalization::Equalization(){
memset(this->statistic_R, 0, LEAVE*sizeof(int)); memset(this->statistic_G, 0, LEAVE * sizeof(int)); memset(this->statistic_B, 0, LEAVE * sizeof(int));}//设置要处理的图片的路径void Equalization::setImage(Mat &image_in){
this->image = image_in;}//分别对图片的RGB值进行直方图统计void Equalization::statistic(){
for (int counter1 = 0; counter1 < this->image.rows; counter1++) {
for (int counter2 = 0; counter2 < this->image.cols; counter2++) {
//数组下标代表灰度值,里面存储的数是该灰度值对应的像素数 if (this->image.channels() == 1)//如果是灰度图像 {
this->statistic_R[this->image.at
(counter1, counter2)]++; } else//如果是彩色图像 {
this->statistic_R[this->image.at
(counter1, counter2)[0]]++; this->statistic_G[this->image.at
(counter1, counter2)[1]]++; this->statistic_B[this->image.at
(counter1, counter2)[2]]++; } } }}//对原图进行均衡处理Mat Equalization::queProcess(){
/*计算原来的各个灰度值经过均衡以后应该变成多少 temp数组下标代表原先图像的灰度值 temp中存储的数是变换后各个灰度值对应的灰度值 */ int temp_R[LEAVE], temp_G[LEAVE], temp_B[LEAVE]; memset(temp_R, 0, LEAVE * sizeof(int)); memset(temp_G, 0, LEAVE * sizeof(int)); memset(temp_B, 0, LEAVE * sizeof(int)); int sumR = 0, sumB = 0, sumG = 0; double const_num = (double)(LEAVE - 1) /(double) (this->image.cols*this->image.rows); for (int counter0 = 0; counter0 < LEAVE; counter0++) {
if (this->image.channels() == 1) {
sumR += this->statistic_R[counter0]; temp_R[counter0] = (int)(const_num * sumR + 0.5); } else {
sumR += this->statistic_R[counter0]; sumG += this->statistic_G[counter0]; sumB += this->statistic_B[counter0]; //进行四舍五入 temp_R[counter0] = (int)(const_num * sumR + 0.5); temp_G[counter0] = (int)(const_num * sumG + 0.5); temp_B[counter0] = (int)(const_num * sumB + 0.5); } } Mat imEqu; if (image.channels() == 1) {
Mat imEqu1(this->image.rows, this->image.cols, CV_8UC1); imEqu1.copyTo(imEqu); } else {
Mat imEqu1(this->image.rows, this->image.cols, CV_8UC3); imEqu1.copyTo(imEqu); } //逐个像素进行处理 for (int counter1 = 0; counter1 < this->image.rows; counter1++) {
for (int counter2 = 0; counter2 < this->image.cols; counter2++) {
if (this->image.channels() == 1) {
imEqu.at
(counter1, counter2) = temp_R[image.at
(counter1, counter2)]; } else { imEqu.at
(counter1, counter2)[0] = temp_R[image.at
(counter1, counter2)[0]]; imEqu.at
(counter1, counter2)[1] = temp_G[image.at
(counter1, counter2)[1]]; imEqu.at
(counter1, counter2)[2] = temp_B[image.at
(counter1, counter2)[2]]; } } } return imEqu;}

四、结果分析

  • 这里顺便贴出main函数:
#include "Equalization.h"#include 
int main(){
namedWindow("原图", CV_WINDOW_AUTOSIZE); Mat image1 = imread("pic.jpg", CV_LOAD_IMAGE_GRAYSCALE); imshow("原灰度图", image1); Equalization equ1; equ1.setImage(image1); equ1.statistic(); Mat new_im1 = equ1.queProcess(); imshow("变换后灰度图像", new_im1); //直方图均衡 Mat image = imread("pic2.jpg", CV_LOAD_IMAGE_COLOR); imshow("原彩色图", image); Equalization equ; equ.setImage(image); equ.statistic(); Mat new_im = equ.queProcess(); imshow("变换后彩色图像", new_im); waitKey(0); return 0;}
  • 处理结果:
    灰度图像:
    在这里插入图片描述
    在这里插入图片描述
    【原图】
    在这里插入图片描述
    【处理后图像】

在这里插入图片描述

五、实验心得

  • 基本都写在前面了
  • 欢迎大家在评论中探讨、斧正。
你可能感兴趣的文章
iOS中使用RNCryptor对资源文件加密
查看>>
Device Tree编译工具dtc
查看>>
softlockup/hardlockup原理详细介绍
查看>>
项目管理学习笔记之八风险管理过程总结
查看>>
项目管理学习笔记之九采购管理过程总结
查看>>
solaris常用命令总结
查看>>
邮件安全证书(S/MIME),如何申请邮件证书
查看>>
Go语言基础入门--简介
查看>>
Go语言基础入门--变量,类型
查看>>
Go语言基础入门--数组,切片,map
查看>>
Go语言基础入门--if,for,range,switch
查看>>
Go语言基础入门--函数,错误处理
查看>>
VIM 学习系列之基本命令,常用命令
查看>>
轻松搭建安全、轻量、极速、简约的博客Eiblog
查看>>
Golang包管理工具Glide,你值得拥有
查看>>
如何降低白噪声对网站用户体验的影响?
查看>>
【BDTC2016】大数据分析与生态系统论坛:大数据存储、处理技术大比评 百花齐放落地实践大展现
查看>>
2017微信公开课PRO版在广州召开 张小龙首次全面解读小程序
查看>>
微信小程序催生新的创业机会 阿拉丁为首批乘风破浪者
查看>>
这里有海量的用户群 CSDN学院诚邀微信小程序技术课程优秀讲师
查看>>