编程实现计算图像直方图、图像熵解析
图像直方图实验报告

图像直方图实验报告实验目的本实验旨在通过使用Python编程语言对图像直方图进行分析和可视化,加深对图像亮度分布的理解,并通过实验结果来探索不同图像的特点和相似性。
实验步骤1. 导入必要的库在开始实验之前,首先需要导入所需的Python库,包括numpy、matplotlib.pyplot和cv2。
可以使用以下代码导入这些库:import numpy as npimport matplotlib.pyplot as pltimport cv22. 读取图像数据选择一张感兴趣的图像作为实验对象,并使用cv2库中的imread()函数读取图像数据。
例如,可以使用以下代码读取名为image.jpg的图像:image = cv2.imread('image.jpg', 0)3. 计算图像直方图使用numpy库中的histogram()函数计算图像的直方图。
直方图是一个表示图像亮度级别频率分布的数组。
可以使用以下代码计算直方图:histogram = np.histogram(image.flatten(), bins=256, range=[0, 256])上述代码将返回一个包含图像直方图数据的数组。
4. 可视化直方图使用matplotlib.pyplot库中的bar()函数将图像直方图可视化。
可以使用以下代码绘制直方图:plt.figure()plt.title('Image Histogram')plt.xlabel('Bins')plt.ylabel('Frequency')plt.bar(histogram[1][:-1], histogram[0], width=1, color='gray')plt.show()上述代码将绘制一个表示图像亮度级别频率分布的直方图。
5. 结果分析通过观察直方图,可以分析图像的亮度特性和分布情况。
Python+OpenCV图像处理之直方图统计

Python+OpenCV图像处理之直⽅图统计⽬录1.直⽅图概述(1)基本概念(2)直⽅图中的术语2.直⽅图绘制(1)读取图像信息(2)绘制直⽅图3.掩膜直⽅图(1)基本概念(2)实现代码4.H-S直⽅图(1)基本概念(2)绘制⼆维H-S直⽅图1. 直⽅图概述(1)基本概念直⽅图就是对图像的另外⼀种解释,它描述了整幅图像的灰度分布。
直⽅图的 x 轴代表灰度值(0~255),y 轴代表图⽚中同⼀种灰度值的像素点的数⽬,所以通过直⽅图我们可以对图像的亮度、灰度分布、对⽐度等有了⼀个直观的认识(2)直⽅图中的术语BINS前⾯说到,直⽅图中的 x 轴表⽰的是灰度值,⼀幅灰度图的灰度等级有 256 级,所以我们是否需要将每⼀个等级标注在⼀条轴上呢?或者如果我们需要的不是每⼀个灰度值的分布,⽽是⼀个范围内的灰度分布呢?所以我们将每⼀个需要的灰度值范围称为⼀个 BIN,即所有的灰度等级被分为⼏个⼩组,每⼀个⼩组是⼀个 BINDIMS代表的是我们收集的图像的参数的数⽬,直⽅图我们如果只收集灰度值⼀个参数,那么该参数的值就是1RANGE代表统计的灰度值的范围,⼀般的范围是[0-255]2. 直⽅图绘制(1)读取图像信息在计算机视觉系列的⽂章中第⼀件事就是读取图像信息:"""Author:XiaoMadate:2021/10/24"""#调⽤需要的包import cv2import matplotlib.pyplot as pltimg0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY) #转化为灰度图h, w = img1.shape[:2]print(h, w)dWindow("W0")cv2.imshow("W0", img1)cv2.waitKey(delay = 0)图像信息如下:419 636(2)绘制直⽅图绘制直⽅图使⽤的函数如下:hist = cv2.calcHist(images, channels, mask, histSize, ranges, accumulate)images:原图channels:指定通道 [0]代表灰度图,如果读⼊的图像不是灰度图,该值可以是[0],[1],[2]分别代表通道 B,G,Rmask:掩码图像,进⾏整张图的绘制时为 NonehistSize:BIN 的数量ranges:像素值范围accumulate:累计标识,⼀般可以省略灰度图的直⽅图#绘制直⽅图hist = cv2.calcHist([img1], [0], None, [256], [0, 255])plt.plot(hist, color = 'lime', label = '直⽅图', linestyle = '--')plt.legend()plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')plt.show()可以看出这幅灰度图中亮度较⾼的像素点还是占多数的,即整体亮度较⾼彩⾊图直⽅图读⼊彩⾊图像,并对某⼀个通道进⾏直⽅图绘制"""Author:XiaoMadate:2021/10/24"""#调⽤需要的包import cv2import matplotlib.pyplot as pltplt.rcParams['font.family'] = 'SimHei' #将全局中⽂字体改为⿊体img0 = cv2.imread('E:\From Zhihu\For the desk\cvseven.jpeg')img1 = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)h, w = img1.shape[:2]print(h, w)dWindow("W0")cv2.imshow("W0", img0)cv2.waitKey(delay = 0)#绘制直⽅图hist = cv2.calcHist([img0], [0], None, [256], [0, 255])plt.plot(hist, color = 'lime', label = '蓝⾊通道直⽅图', linestyle = '--', alpha = 1)plt.legend()plt.savefig('E:\From Zhihu\For the desk\cvseven1.jpeg')plt.show()上图就是对蓝⾊通道绘制的直⽅图3. 掩膜直⽅图(1)基本概念如果我们不需要整幅图像中的直⽅图,⽽是某个区域的直⽅图,我们只需要绘制⼀幅图,将需要统计的部分设置为⽩⾊,不需要统计的部分设置为⿊⾊,就构成了⼀幅掩膜图像(2)实现代码得到掩模图##得到掩膜图mask = np.zeros(img0.shape, np.uint8) #将每⼀个像素点设置为0,就是⿊⾊mask[109:309, 212:412] = 255 #选取特定区域设置为⽩⾊img0_1 = cv2.bitwise_and(img0, mask) #图像与操作得到掩膜图dWindow("W1")cv2.imshow("W1", img0_1)cv2.waitKey(delay = 0)绘制掩膜直⽅图#绘制掩膜直⽅图##得到掩膜图mask = np.zeros(img1.shape, np.uint8) #将每⼀个像素点设置为0,就是⿊⾊mask[109:309, 212:412] = 255 #选取特定区域设置为⽩⾊img1_1 = cv2.bitwise_and(img1, mask) #图像与操作得到掩膜图dWindow("W1")cv2.imshow("W1", img1_1)cv2.waitKey(delay = 0)##绘制掩膜直⽅图和部分图像直⽅图hist1 = cv2.calcHist([img1], [0], mask, [256], [0, 255]) #掩膜图直⽅图,参数需要修改hist2 = cv2.calcHist([img1], [0], None, [256], [0,255])plt.plot(hist1, color = 'b', label = '掩膜直⽅图', linestyle = '--')plt.plot(hist2, color = 'r', label = '原图直⽅图', linestyle = '-.')plt.legend()plt.savefig('E:\From Zhihu\For the desk\cvseven2.jpeg')plt.show()得到的图像如下:4. H-S 直⽅图(1)基本概念H(Hue) - S(Saturation) 直⽅图,即⾊调 - 饱和度直⽅图绘制该直⽅图需要将源RGB图像转化到 HSV (⾊调、饱和度、亮度)颜⾊空间中去img0_2 = cv2.cvtColor(img0, cv2.COLOR_BGR2HSV) #将 RGB 空间转化为 HSV 空间dWindow("W2")cv2.imshow("W2", img0_2)cv2.waitKey(delay = 0)(2)绘制⼆维H-S直⽅图此处参考:##绘制H-S直⽅图hist3 = cv2.calcHist ([img0_2], [0, 1], None , [180, 256], [0, 180, 0, 256])#官⽹给出的解释:channel = [0,1] 因为我们需要同时处理 H 和 S 平⾯;bins = [180,256] H 平⾯为 180,S 平⾯为 256;range = [0,180,0,256] ⾊调值介于 0 和 180 之间,饱和度介于 0 和 2 plt.imshow(hist3)plt.savefig('E:\From Zhihu\For the desk\cvseven3.jpeg')plt.show()得到的图像如下:上图中的 X 轴代表S(饱和度),Y轴代表H(⾊调)该图中的峰值主要分布在 S 在(0-50)之间 H在(20-80),⾄于为什么峰值较少,个⼈猜测是由于原图中的⾊彩变化不明显,导致没办法绘制出过多过明显的峰值到此这篇关于Python+OpenCV图像处理之直⽅图统计的⽂章就介绍到这了,更多相关Python OpenCV直⽅图统计内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
C++彩色图像(RGB)三通道直方图计算和绘制,图像逆时针旋转90°实现代码

C++彩⾊图像(RGB)三通道直⽅图计算和绘制,图像逆时针旋转90°实现代码1 #include "iostream"2 #include "opencv2/opencv.hpp"3 #include "vector"45using namespace std;6using namespace cv;78/*计算真彩⾊图像的直⽅图*/9void splitRgbImgPro(const Mat img, vector<Mat>& imgRGB);10void calImgHistPro(vector<Mat> imgrgb, vector<vector<int>>& histData);11void showImgHistPro(vector<vector<int>>& histD);12void rotateImgPro(Mat& img, float angle);13int main()14 {15 Mat imgSrc = imread("E:\\VideoPlateRecog\\ETC\\1008\\SRC\\144.bmp");16/*⾊彩空间分离*/17 vector<Mat> imgRGB;18 splitRgbImgPro(imgSrc, imgRGB);19/*计算三通道直⽅图*/20 vector<vector<int>> histData;21 calImgHistPro(imgRGB, histData);22/*绘制三通道直⽅图*/23 showImgHistPro(histData);2425 system("pause");26return0;27 }2829void calImgHistPro(vector<Mat> imgrgb,vector<vector<int>>& histData)30 {31 vector<Mat> imgrgbSrc = imgrgb;32int width = imgrgb[0].cols;33int height = imgrgb[0].rows;34for (int n = 0; n < imgrgb.size(); n++)35 {36 Mat imgSrc = imgrgbSrc[n].clone();37int img_sum = -1;38 vector<int> p(256);39for (int m = 0; m <p.size() ; m++)40 {41 p[m] = 0;42 }43for (int i = 0; i < height; i++)44 {45 uchar* ptr = imgSrc.ptr<uchar>(i);46for (int j = 0; j < width; j++)47 {48int k = ptr[j];49 p[k]++;50 }51 }52/*find max element of vector*/53for (auto it = p.begin(); it != p.end(); it++)54 {55if (*it > img_sum)56 {57 img_sum = *it;58 }59 }60for (int m = 0; m < 256; m++)61 {62 p[m] = p[m]*255 / img_sum;63 }64 histData.push_back(p);65 }66 }6768void showImgHistPro(vector<vector<int>>& histD)69 {70 vector<vector<int>> histSrc=histD;71int cols = histD[0].size();72int rows = -1;73 Mat histRGB(cols , cols * 3, CV_8UC1, Scalar(0));74for (int n = 0; n < histD.size(); n++)75 {76 vector<int> hist = histD[n];77 Mat histImg(cols, cols, CV_8UC1, Scalar(0));78for (int i = 0; i < cols; i++)79 {80 uchar* ptr = histImg.ptr(i);81for (int j = 0; j < hist[i]; j++)82 {83 ptr[j] = 255;84 }85 }86/*旋转90°*/87 Mat histImg1(cols, cols, CV_8UC1, Scalar(0));88for (int l = 0; l < cols; l++)89 {90for (int k = 0; k < cols; k++)91 {92 histImg1.at<uchar>(l, k) = histImg.at<uchar>(k, cols-l-1);93 }94 }95 histImg1.copyTo(histRGB(Rect(cols*n,0, cols, cols)));96 }97 imshow("Img_R_G_B", histRGB);98 waitKey(0);99 }100101void rotateImgPro(Mat& img,float angle)102 {103 Mat retMat(img.cols, img.rows, CV_8UC1, Scalar(0));104float anglePI = (float)(angle*CV_PI / 180);105int xSm, ySm;106for (int i = 0; i < retMat.rows; i++)107 {108for (int j = 0; j < retMat.cols; j++)109 {110 xSm = (int)((i - retMat.rows / 2)*cos(anglePI) -111 (j - retMat.cols / 2)*sin(anglePI) + 0.5);112 ySm = (int)((i - retMat.rows / 2)*sin(anglePI) +113 (j - retMat.cols / 2)*cos(anglePI) + 0.5);114 retMat.at<uchar>(i, j) = img.at<uchar>(xSm, ySm); 115116 }117 }118 }119120121122123void splitRgbImgPro(const Mat img, vector<Mat>& imgRGB)124 {125 Mat imgSrc = img.clone();126int width = imgSrc.rows;127int height = imgSrc.cols;128 Mat imgR(width, height, CV_8UC1);129 Mat imgG(width, height, CV_8UC1);130 Mat imgB(width, height, CV_8UC1);131for (int i = 0; i < width; i++)132 {133 Vec3b* imgPtr = imgSrc.ptr<Vec3b>(i);134 uchar* imgSPtr = imgSrc.ptr<uchar>(i);135 uchar* imgRPtr = imgR.ptr<uchar>(i);136 uchar* imgGPtr = imgG.ptr<uchar>(i);137 uchar* imgBPtr = imgB.ptr<uchar>(i);138for (int j = 0; j < height; j++)139 {140 imgRPtr[j] = imgSPtr[0];141 imgGPtr[j] = imgSPtr[1];142 imgBPtr[j] = imgSPtr[2];143 imgSPtr += 3;144 }145 }146 imgRGB.push_back(imgR);147 imgRGB.push_back(imgG);148 imgRGB.push_back(imgB);149 }。
关于信源熵的实验报告讲解

实验报告实验名称关于信源熵的实验课程名称信息论与编码姓名xxx 成绩90班级电子信息1102学号**********日期2013.11.22地点综合实验楼实验一关于信源熵的实验一、实验目的1. 掌握离散信源熵的原理和计算方法。
2. 熟悉matlab 软件的基本操作,练习使用matlab 求解信源的信息熵。
3. 自学图像熵的相关概念,并应用所学知识,使用matlab 或其他开发工具求解图像熵。
4. 掌握Excel的绘图功能,使用Excel绘制散点图、直方图。
二、实验原理1. 离散信源相关的基本概念、原理和计算公式产生离散信息的信源称为离散信源。
离散信源只能产生有限种符号。
随机事件的自信息量I(xi)为其对应的随机变量xi 出现概率对数的负值。
即: I (xi )= -log2p ( xi)随机事件X 的平均不确定度(信源熵)H(X)为离散随机变量 xi 出现概率的数学期望,即:2.二元信源的信息熵设信源符号集X={0,1} ,每个符号发生的概率分别为p(0)= p,p(1)= q,p+ q =1,即信源的概率空间为:则该二元信源的信源熵为:H( X) = - plogp–qlogq = - plogp –(1 - p)log(1- p)即:H (p) = - plogp –(1 - p)log(1- p) 其中 0 ≤ p ≤13. MATLAB二维绘图用matlab 中的命令plot( x , y) 就可以自动绘制出二维图来。
例1-2,在matlab 上绘制余弦曲线图,y = cos x ,其中 0 ≤ x ≤2。
>>x =0:0.1:2*pi; %生成横坐标向量,使其为 0,0.1,0.2,…,6.2>>y =cos(x ); %计算余弦向量>>plot(x ,y ) %绘制图形4. MATLAB求解离散信源熵求解信息熵过程:1) 输入一个离散信源,并检查该信源是否是完备集。
用MATLAB统计图像直方

02
imhist(I); % 计算并显示归一化直方图
03
```
04
直方图均衡化
直方图均衡化的定义
直方图均衡化是一种图像处理技术, 通过对图像的灰度直方图进行变换, 改善图像的对比度,增强图像的细节 和清晰度。
通过扩展图像的灰度级别范围,使得 图像的细节更加突出,提高图像的可 视化效果。
Matlab实现直方图均衡化
01 使用Matlab中的`histeq`函数,可以对图 像进行直方图均衡化处理。
02 首先,读取图像文件并将其转换为灰度图 像。
03
然后,使用`histeq`函数对灰度图像进行直 方图均衡化处理。
04
最后,显示处理后的图像。
直方图均衡化的效果
01
02
03
直方图均衡化可以显著 改善图像的对比度,增 强图像的细节和清晰度
彩色图像直方图
示例代码
1
```matlab
2
3
I = imread('image.jpg'); % 读取彩色图像
彩色图像直方图
imhist(I); % 计算并显示彩色直方图 ```
归一化直方图
归一化直方图
归一化直方图是一种将像素值范围限制在特定范围内的直方图,可以更好地反映图像的细节和特征。 在Matlab中,可以使用`imhist`函数计算归一化直方图。
直方图可以用于提取图像中的特征,如边缘、纹理等,也可以用于 图像分割,将图像划分为不同的区域。
直方图的计算方法
01
累积直方图
02
归一化直方图
首先计算原始直方图,然后将每个像 素强度值的频数累加起来,得到累积 直方图。累积直方图可以用于快速查 找特定像素强度值的范围。
信息熵与图像熵的计算

实验一信息熵与图像熵计算一、实验目的1.复习MATLAB 的基本命令,熟悉MATLAB 下的基本函数。
2.复习信息熵基本定义, 能够自学图像熵定义和基本概念。
二、实验仪器、设备1.计算机-系统最低配置 256M 内存、P4 CPU。
2.Matlab 仿真软件- 7.0 / 7.1 / 2006a 等版本Matlab 软件。
三、实验内容与原理(1)内容:1.能够写出MATLAB 源代码,求信源的信息熵。
2.根据图像熵基本知识,综合设计出MATLAB 程序,求出给定图像的图像熵。
(2)原理1. MATLAB 中数据类型、矩阵运算、图像文件输入与输出知识复习。
2.利用信息论中信息熵概念,求出任意一个离散信源的熵(平均自信息量)。
自信息是一个随机变量,它是指某一信源发出某一消息所含有的信息量。
所发出的消息不同,它们所含有的信息量也就不同。
任何一个消息的自信息量都代表不了信源所包含的平均自信息量。
不能作为整个信源的信息测度,因此定义自信息量的数学期望为信源的平均自信息量:信息熵的意义:信源的信息熵H是从整个信源的统计特性来考虑的。
它是从平均意义上来表征信源的总体特性的。
对于某特定的信源,其信息熵只有一个。
不同的信源因统计特性不同,其熵也不同。
3.学习图像熵基本概念,能够求出图像一维熵和二维熵。
图像熵是一种特征的统计形式,它反映了图像中平均信息量的多少。
图像的一维熵表示图像中灰度分布的聚集特征所包含的信息量,令Pi 表示图像中灰度值为i的像素所占的比例,则定义灰度图像的一元灰度熵为:255log i iip p ==∑H图像的一维熵可以表示图像灰度分布的聚集特征,却不能反映图像灰度分布的空间特征,为了表征这种空间特征,可以在一维熵的基础上引入能够反映灰度分布空间特征的特征量来组成图像的二维熵。
选择图像的邻域灰度均值作为灰度分布的空间特征量,与图像的像素灰度组成特征二元组,记为( i, j ),其中i 表示像素的灰度值(0 <= i <= 255),j 表示邻域灰度(0 <= j <= 255),2(,)/ijP f i j N =上式能反应某像素位置上的灰度值与其周围像素灰度分布的综合特征,其中f(i, j) 为特征二元组(i, j)出现的频数,N 为图像的尺度,定义离散的图像二维熵为:255logij ijip p ==∑H构造的图像二维熵可以在图像所包含信息量的前提下,突出反映图像中像素位置的灰度信息和像素邻域内灰度分布的综合特征.四、实验步骤1.求解信息熵过程:1) 输入一个离散信源,并检查该信源是否是完备集。
图像霍夫曼编码与解码以及熵,平均码长,冗余度的计算

DIP上机报告题目:数字图像处理上机报告(第4次)学校:中国地质大学(武汉)***师:****名:**班级序号: 071112-06目录1图像霍夫曼编码与解码以及熵,平均码长,冗余度的计算错误!未定义书签。
2上机小结 (10)注:给定的文件夹中只需运行test脚本就可以得到结果,从workspace中看到相应的数据4.2图像的霍夫曼编码与解码题目要求:对图2实施哈夫曼编码和解码,计算图象熵,平均码长和冗余度;算法设计:1.遍历图像,统计各个像素灰度值的概率2.找出概率最小的两个,在最小概率所代表的灰度值编码中加1,在另一个较小的概率所代表的灰度值编码中加03.合并两个概率,成为一个新的元素,如此重复下去,直到最后剩两个元素4.进行编码的逆过程,即解码过程5.计算相应的数据程序代码:运行代码:clearin=[2,2,3,5,0,0,5,5,5,4,1,1,2,2,1,5,4,6,5,5,7,2,2,3,5,2,2,2,3,4,4,4,6,2,1,4,1,1,2,2,1,5,7,6,5,5,7,2,2,4,4,1,2,2,1,5,2,3,1,2,2,1,5,0];[p,out] = gailv( in );[code] = Huffman(0:7,p); %进行霍夫曼编码[Coded_Img]=Encode(in,code); %对图像进行编码[H,L,R]=GetInfo(code); %计算熵、平均码长、冗余度[Img]=Decode(Coded_Img,code); %对图像进行解码图像各像素灰度的概率计算:function[ p,out ]=gailv( in )[M,N]=size(in);out = zeros(4,8);p = zeros(1,8);for i=1:8out(1,i)=i-1;endfor i=1:Mfor j=1:Nfor k=1:8if in(i,j) == out(1,k)out(2,k)=out(2,k)+1;endendendendfor i=1:8out(3,i)=out(2,i)/(M*N);p(1,i)=out(2,i)/(M*N);endend霍夫曼编码过程:function [code_out] = Huffman(s,p)[Ms,Ns]=size(s);if (Ms==1)sig=s';elsesig=s;end%s为各元素名称 p为各元素概率[Ms,Ns]=size(sig);[Mp,Np]=size(p);if (Ms~=Np)return;endcode=cell(Ms,4);%建立编码cellcode_out=cell(Ms,3);%建立输出cellcoding=cell(Ms,2);%建立编码过程中用到的cellfor i=1:Mscode{i,1}=sig(i,:);%第一列为元素名称code{i,2}=[];%第二列为编码code{i,3}=p(i);%第三列为元素概率code{i,4}=[];%第四列为元素概率排行coding{i,1}=p(i);%第一行为元素概率coding{i,2}=i;%第二行表示此概率由哪些元素组成end[m,l]=Cell_min(coding(:,1));%找出最小值while (m<1)%若最小值小于1(编码尚未完成)[m1,l1]=Cell_min(coding(:,1));%找出最小值temp_p=coding{l1,1};%记录下最小概率coding{l1,1}=2;%将概率改为2,则以后不会再次取到[m2,l2]=Cell_min(coding(:,1));%找出次小值coding{l2,1}=coding{l2,1}+temp_p;%最小概率和次小概率相加得到新元素概率[k,mp]=size(coding{l1,2});%考虑最小概率包含了哪些元素for i=1:mpcode{coding{l1,2}(i),2}=[1,code{coding{l1,2}(i),2}];%在这些元素的编码前加1end[k,mp]=size(coding{l2,2});%考虑次小概率包含了哪些元素for i=1:mpcode{coding{l2,2}(i),2}=[0,code{coding{l2,2}(i),2}];%在这些元素的编码前加0endcoding{l2,2}=[coding{l2,2},coding{l1,2}];%新元素包含了次小和最小元素包含的所有元素[m,l]=Cell_min(coding(:,1));%找出当前最小值,继续循环endfor i=1:Mscode_out(i,1:3)=code(i,1:3);%输出cell前3列等于编码cell前3列end求概率的最小值函数:function [mind,loc]=Cell_min(data)%找出cell中的某列元素的最小值和位置[M,N]=size(data);loc=-1;for i=1:Md(i)=data{i}(1,1);endturemin=min(d);%找出最小值for i=1:M %遍历矩阵,找出最小值所在位置if (d(i)==turemin)mind=d(i);loc=i;return;endendend图像编码代码:function [Coded_Img]=Encode(img,code)%遍历图像,查表确定码字[M,N]=size(img);[Mc,Nc]=size(code);Coded_Img=cell(M,N);for i=1:Mfor j=1:Ndata=img(i,j);for k=1:Mcif (code{k,1}==data)Coded_Img{i,j}=code{k,2};endendendendend图像解码代码:function [img]=Decode(Coded_Img,code)%遍历编码图像,查表确定数值[M,N]=size(Coded_Img);[Mc,Nc]=size(code);for i=1:Mfor j=1:Ndata=Coded_Img{i,j};for k=1:Mcif(size(data)==size(code{k,2}))if (code{k,2}==data)img(i,j)=code{k,1};endendendendendend相关数据的计算:function [H,L,R]=GetInfo(code)[M,N]=size(code);H=0;for i=1:MH=H+code{i,3}*log2(1/code{i,3});end%计算熵L=0;for i=1:M[m,n]=size(code{i,2});L=L+code{i,3}*n;end%计算平均码长R=L/H-1;%计算冗余度end运行结果:编码前图像:编码后图像:解码后图像:熵(H)、平均码长(L)、冗余度(R)至此,成功实现了图像矩阵的编码和解码以及相关参数的计算。
数字图像实验 图像直方图分析1234

试验三:图像直方图分析一·实验目的1.掌握VC++6.0图像编程的基本操作2. 应用VC++6.0编程绘制灰度直方图。
二·实验内容1.用VC++6.0绘制灰度直方图;2. 对图像进行直方图分析。
三·实验步骤(1)启动VC++6.0,打开Dip工程。
(2)将Pointpro.h、Pointpro.cpp文件及Areapro.h、Areapro.cpp文件拷贝到当前工程目录文件里面。
(3)在Fileview-->Dipfiles→右键→Setting→Link→添加Pointpro.h、Pointpro.cpp 文件及Areapro.h、Areapro.cpp文件。
(4)在菜单栏→insert→resouce→dialog→new,在对话框模版的非控制区点击鼠标右键,在弹出的对话框中选properties,设置为ID:IDD_DLG_Intensity,C标题:Histogram,关闭属性对话框,回到“建立类向导”(MFC classwizard),在弹出的对话框中选创建新类CDlgIntensity后确定。
并且在FileView中修改DlgIntensity.cpp和DlgIntensity.h相应的代码;(5)在弹出的对话框中,添加如下的按钮等控件:例如右键单击上面最大的静态文本,在弹出的对话框中选“属性”,在属性对话框中添加如下内容:(6)在ResourceView栏中→Menu→选IDR_DIPTYPE ,如图在View菜单栏下空的一栏中,右键鼠标,在弹出的对话框中选属性properties,在弹出的对话框中,设置:ID:ID_VIEW_HIST,标题为Histogram,在建立的类向导中选类为CDlgIntensity,确定。
(7)在StdAfx.h中添加#include<math.h>(8)在DipView.h中//{{AFX_MSG(CDipView)下添加afx_msg void OnViewHist();afx_msg void OnUpdateViewHist(CCmdUI* pCmdUI); (9)DipView.cpp添加#include "PointPro.h"和#include "DlgIntensity.h",在BEGIN_MESSAGE_MAP(CDipView, CScrollView)处添加:ON_COMMAND(ID_VIEW_HIST, OnViewHist)ON_UPDATE_COMMAND_UI(ID_VIEW_HIST, OnUpdateViewHist) 在// CDipView message handlers下面添加:void CDipView::OnViewHist(){CDipDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);//判断当前是否有图像对象if( pDoc->m_pDibObject == NULL ) return;//在点处理CPointPro类中创建用来绘制直方图的数据CPointPro PointOperation( pDoc->m_pDibObject );int *pHistogram = PointOperation.GetHistogram();//生成一个对话框CHistDlg类的实例CDlgIntensity HistDlg;//将绘制直方图的数据传递给CHistDlg对话框类的公有成员变量m_pnHistogramif( pHistogram != NULL ){//设置直方图数据指针HistDlg.m_pnHistogram = pHistogram;//设置当前像素值为0的像素数HistDlg.m_nCurrentPiexsNum = pHistogram[0];//设置是否为256级灰度图像HistDlg.m_bIsGray256 = PointOperation.IsGray256();}//显示对话框if ( HistDlg.DoModal() != IDOK)return;delete [] pHistogram;}void CDipView::OnUpdateViewHist(CCmdUI* pCmdUI){CDipDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);pCmdUI->Enable( pDoc->m_pDibObject->GetNumBits() >= 8);}(10)在DipDoc.h中添加:protected:long m_lHeight;long m_lWidth;(11)在DipDoc.cpp中添加菜单命令:#include "AreaPro.h",在CDipDoc::CDipDoc()下面添加{m_pDibObject = NULL;m_bImageLoaded = FALSE;// TODO: add one-time construction code herem_lHeight = 0;m_lWidth = 0;}在最下面添加:void CDipDoc::OnFileSaveAs(){// TODO: Add your command handler code herestatic int nIndex = 1;CFileDialog DialogSaveAs( FALSE, NULL, m_pDibObject->GetImageName(),OFN_HIDEREADONLY, szFilter );DialogSaveAs.m_ofn.nFilterIndex = (DWORD) nIndex;if( DialogSaveAs.DoModal() == IDOK ){CMainFrame *pMainFrame = ( CMainFrame * )AfxGetMainWnd();CChildFrame *pChildFrame = ( CChildFrame * )pMainFrame->MDIGetActive();CDipView *pDipView = ( CDipView * )pChildFrame->GetActiveView();nIndex = (int) DialogSaveAs.m_ofn.nFilterIndex;if( nIndex == 5 ){if( m_pDibObject->GetNumBits() != 24 ){AfxMessageBox("必须是24位真彩色图像才能存为JPEG格式!");return;}}if( m_pDibObject != NULL ){CString strPathName = DialogSaveAs.GetPathName();int nFindIndex = strPathName.Find(".");if( nFindIndex != -1)strPathName = strPathName.Left( nFindIndex );strPathName += CDibObject::szExtensions[ nIndex - 1 ];//m_pDibObject->ProcessImageHeader();//m_pDibObject->ProcessPalette();m_pDibObject->Save( strPathName );CString strFileName = DialogSaveAs.GetFileName();nFindIndex = strFileName.Find(".");if ( nFindIndex != -1 )strFileName = strFileName.Left( nFindIndex );strFileName += CDibObject::szExtensions[ nIndex - 1 ];pChildFrame->SetWindowText( strFileName );SetPathName( strPathName );if( nIndex == 5 ){m_pDibObject->Load( strPathName );pDipView->InvalidateRect( NULL, FALSE );pDipView->UpdateWindow();}}}}(12)在ChildFrm.h中添加public:CChildFrame();int m_nWidth, m_nHeight;(13)在ChildFrm.cpp中添加CChildFrame::CChildFrame(){m_nWidth = 300;m_nHeight = 150;}在BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs)添加:{// TODO: Modify the Window class or styles here by modifying// the CREATESTRUCT cscs.cx = m_nWidth;cs.cy = m_nHeight;if( !CMDIChildWnd::PreCreateWindow(cs) ) return FALSE;return TRUE;}一、实验结果二、实验心得及体会通过做这次实验,使我又学到了关于图像直方图的知识,进一步掌握了图像编程的基本操作:会应用VC++6.0编程绘制灰度直方图。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数字图像处理实验报告——图像常用格式及显示武汉大学2016.041 实验内容本实验报告主要介绍主要内容1. 理解灰度映射原理;2. 掌握灰度映射计算方法;3. 理解图像直方图的定义;4. 理解图像直方图的作用;5. 理解图像熵的定义及作用;6. 掌握图像直方图计算方法;7. 掌握图像熵的计算方法;8. 进一步熟悉图像文件256色、24位真彩色BMP图像格式;9. 进一步熟悉Visual C++ 6.0编程界面,及使用方法;10. 熟悉Visual C++中绘图函数方法;11. 编程完成计算图像几种灰度映射;12. 编程实现计算图像直方图、图像熵;13. 编程绘制图像直方图;14. 根据不通灰度映射处理观察图像直方图变化;15. 总结实验过程(实验报告):编程、调试、结果、分析、结论。
主要目的1. 建立相关实验环境:从指定服务器指定位置拷贝实验相关材料,包括:实验要求,实例程序,示例图像,VC++6.0程序,实验相关幻灯片;2. 使用实验一建立的简单多文档应用程序框架及、图像夺取和显示功能,进一步熟悉图像的格式及显示,熟悉图像的组织和存储方式。
3. 编写图像线性灰度映射:4. 编写图像直方图统计程序:5. 观察图像直方图主要函数说明1.void CZhangyanImageView::OnProcessZhifangtu()函数目的:在用户界面中添加直方图处理,并添加函数在.cpp文件中函数参数说明:建立直方图处理函数2.void CZhangyanImageView::OnProcessLinetran()函数目的:在用户界面中添加灰度变换处理,并添加函数在.cpp文件中函数参数说明:建立灰度变换处理函数主要代码注释1.灰度变换函数代码CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits;//把文件中的m_pBits赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight;//定义整形的image图片宽和高int nValue=0;double dValue=0.0;long lTotal=0;long lTotalD=0;long lTotalL=0;int ab=100,bb=255,a=0,b=255;//定义原图像的灰度值0-255范围,定义处理后图像灰度值100-255范围if(pBits==NULL) return ;//遍历完成则返回for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;//统计出宽*当前高for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;//统计出第几个像素nValue=*(pBits+lTotalD);// 采用int nValue= *(m_pBits imageWidth * i+j )公式获得图像点灰度值dValue=ab+1.0*(bb-ab)/(b-a)*(nValue-a);//套用灰度变换公式pBits[lTotalD]=int(dValue);}}//对图像进行遍历与灰度处理Invalidate();//强制显示改变了的图像2.直方图生成函数m_bShow=TRUE;CZhangyanImageDoc* pDoc = GetDocument();//定义引用doc的指针ASSERT_V ALID(pDoc);unsigned char * pBits=pDoc->m_pBits; //把文件中的m_pBits图像指针赋予pBitsint nWidth=pDoc->imageWidth;int nHeight=pDoc->imageHeight; //定义整形的image图片宽和高int nValue=0;long lTotal=0;long lTotalD=0;long lTotalL=0;dMax=0;dMaxG=0;dMaxB=0;//数据初始化赋值存储图像灰度像素的计数if(pBits==NULL) return ;if(pDoc->m_nColorBits==8) //对图像进行是否是8彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=lTotalL+j;nValue=*(pBits+lTotalD);//统计灰度值m_lValue[nValue]=m_lValue[nValue]+1;//加1 }}lTotal=nWidth*nHeight;for(INT k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];}}//对图像进行遍历并统计直方图数据long nValueG=0;long nValueB=0;//统计R G Bif(pDoc->m_nColorBits==24) //对图像进行是否是24彩色的判断{for(int k=0;k<256;k++){m_lValue[k]=0;m_dValue[k]=0.0;m_lValueG[k]=0;m_dValueG[k]=0.0;m_lValueB[k]=0;m_dValueB[k]=0.0;//}for(int i=0;i<nHeight;i++){lTotalL=nWidth*i;for(int j=0;j<nWidth;j++){lTotalD=(lTotalL+j)*3;nValue=*(pBits+lTotalD);m_lValue[nValue]=m_lValue[nValue]+1;nValueG=*(pBits+lTotalD+1);m_lValueG[nValueG]=m_lValueG[nValueG]+1;nValueB=*(pBits+lTotalD+2);m_lValueB[nValueB]=m_lValueB[nValueB]+1;}}lTotal=nWidth*nHeight;for(int k=0;k<256;k++){m_dValue[k]=1.0*m_lValue[k]/lTotal;if(dMax<m_dValue[k]) dMax=m_dValue[k];m_dValueG[k]=1.0*m_lValueG[k]/lTotal;if(dMaxG<m_dValueG[k]) dMaxG=m_dValueG[k];m_dValueB[k]=1.0*m_lValueB[k]/lTotal;if(dMaxB<m_dValueB[k]) dMaxB=m_dValueB[k];}}//对图像进行遍历并统计直方图数据Invalidate();/强制显示改变了的图像3.变量声明void DrawGraph(CDC * pDC);//绘制直方图函数long m_lValue[256];//红色分量灰度统计double m_dValue[256];// 红色分量灰度频数long m_lValueG[256]; //绿色分量灰度统计double m_dValueG[256]; // 绿色分量灰度频数long m_lValueB[256]; //蓝色分量灰度统计double m_dValueB[256]; //蓝色分量灰度频数double dMax,dMaxG,dMaxB;//红、绿、蓝频数最大值BOOL m_bShow;//是否显示直方图4.图形绘制CZhangyanImageDoc* pDoc = GetDocument();ASSERT_V ALID(pDoc);// CCCJImageDoc* pDoc 在各人的程序中不一样unsigned char * pBits=pDoc->m_pBits;int X0=0+5;int Y0=510;int WX=768+3,HY=500;int H=375;int W=256;CPen cyPen(PS_SOLID,2,RGB(255,255,0));CPen * oldPen=pDC->SelectObject(&cyPen);pDC->MoveTo(X0,Y0);pDC->LineTo(X0+WX,Y0);pDC->MoveTo(X0,Y0);pDC->LineTo(X0,Y0-HY);pDC->MoveTo(X0,Y0-HY);pDC->LineTo(X0+WX,Y0-HY);pDC->MoveTo(X0+WX,Y0);pDC->LineTo(X0+WX,Y0-HY);pDC->SelectObject(&oldPen);//设置直方图的区域{CPen redPen(PS_SOLID,1,RGB(255,0,0));oldPen=pDC->SelectObject(&redPen);for(int i=0;i<256;i++){int x0,y0,x1,y1;double dy;x0=X0+i*3;y0=Y0;x1=X0+i*3;dy=Y0-1.0*H*m_dValue[i]/dMax;y1=int(dy+0.5);pDC->MoveTo(x0,y0);pDC->LineTo(x1,y1); //进行绘图操作}pDC->SelectObject(oldPen);//以下略去对于24位的解释1.1灰度变换结果图灰度变换结果1.2图像直方图图读取图像直方图2实验日志2.1实验中遇到问题较于上次试验,本次试验显得轻车熟路许多,内容与调试也比较简单,感觉编写实验报告中遇到的最大困难就是对代码的阐述。
C++中指针是比较难的,再加上vs开发中结构架构的重叠,各种的声明,比较复杂,仔细的阅读了懂得了int nValue= *(m_pBits imageWidth * i +j )代表了灰度值的获取,再结合灰度变换的公式,就很快清楚了进行灰度变换函数的意思,对于直方图数据采集中出现的很多变量感觉不好理解,对于DrawGraph函数绘制的理解还是比较弱的,希望下次实验时让学长来解疑答惑,总之,这次试验按部就班的成功完成,要尽力完善一下自己对c++的理解,获益匪浅。