我是靠谱客的博主 高兴鞋垫,这篇文章主要介绍C语言实现直方图均衡化,现在分享给大家,希望可以做个参考。

直方图均衡化部分是用c语言写的,最后用opencv显示原图像,处理后图像以及原图和处理后图的灰度直方图。

虽然做出来了,均衡化效果还可以,但不知道为什么处理后图像中有三条白线,真心搞不懂,有看出来问题的大神麻烦留言告诉我,谢谢。

(终于知道哪出问题了,原来是每行字节数求错了,改为LineByte=(width*8/8+3)/4*4;即可。)

下面是代码:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#include "stdafx.h" #include<stdio.h> #include<windows.h> #include<opencv2highguihighgui.hpp> #include<opencv2corecore.hpp> #include<cv.h> int main(void) { int width;//图像宽度 int height;//图像高度 RGBQUAD *pColorTable; unsigned char *pBmpBuf,*pBmpBuf1; BITMAPFILEHEADER bfhead; BITMAPINFOHEADER bihead; FILE *fp1=fopen("e:\picture\dog.bmp","rb"); if(fp1==0) return 0; fread(&bfhead,14,1,fp1); fread(&bihead,40,1,fp1); width=bihead.biWidth; height=bihead.biHeight; pColorTable=new RGBQUAD[256]; fread(pColorTable,4,256,fp1); int LineByte=0; LineByte=(width*1/4+1)*4; <span style="white-space:pre"> </span>//LineByte=(width*8/8+3)/4*4; pBmpBuf = new unsigned char[LineByte*height]; fread(pBmpBuf,LineByte*height,1,fp1); fclose(fp1); pBmpBuf1=new unsigned char[LineByte*height]; //用于存储均值化后的图像数据 //统计每个灰度级像素点的个数 int N[256]={0}; for(int i=0;i<height;i++) for(int j=0;j<width;j++) { unsigned char *pb1,*pb2; pb1=pBmpBuf+i*LineByte+j; N[*pb1]++; pb2=pBmpBuf1+i*LineByte+j; *pb2=*pb1; } /*for(int i=0;i<256;i++ ) printf("%d ",N[i]);*/ //统计最小与最大灰度值 int minGrayValue=255; int maxGrayValue=0; for(int i=0;i<height;i++) for(int j=0;j<width;j++) { unsigned char *pb; pb=pBmpBuf+i*LineByte+j; if(*pb>maxGrayValue) maxGrayValue=*pb; else if(*pb<minGrayValue) minGrayValue=*pb; } printf("%d ,%dn",minGrayValue,maxGrayValue);//输出最大与最小灰度值 int x=maxGrayValue-minGrayValue+1; float *p; p=new float[x]; for(int i=0;i<x;i++) { *(p+i)=(float)N[i]/(float)(width*height); //*(p+i)中存放的是灰度级为i的像素在整幅图像中出现 //的概率(即*(p+i)i=0,1,2,3...中存放的就是这幅图像归一化后的直方图) } float *c; c=new float[x]; //定义c,用来存放累积的归一化直方图 for(int i=0;i<x;i++) //对c进行初始化 { *(c+i)=0; } for(int i=0;i<x;i++) { for(int j=0;j<=i;j++) { *(c+i)+=*(p+j); } } for(int i=0;i<height;i++) for(int j=0;j<width;j++) { unsigned char *pb; pb=pBmpBuf1+i*LineByte+j; *pb=*(c+*pb)*(maxGrayValue-minGrayValue)+minGrayValue; } FILE *fp2=fopen("junhenghua.bmp","wb"); fwrite(&bfhead,14,1,fp2); fwrite(&bihead,40,1,fp2); fwrite(pColorTable,4,256,fp2); fwrite(pBmpBuf1,LineByte*height,1,fp2); fclose(fp2); //显示原图与处理后的图像 IplImage *src1=cvLoadImage("e:\picture\dog.bmp"); IplImage *src2=cvLoadImage("junhenghua.bmp"); cvNamedWindow("原图"); cvNamedWindow("处理后图"); cvShowImage("原图",src1); cvShowImage("处理后图",src2); //显示原图像与处理后图像的灰度直方图 int size=256; float range[]={0,255}; float *ranges[]={range}; CvHistogram *hist1=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1);//创建一维直方图, CvHistogram *hist2=cvCreateHist(1,&size, CV_HIST_ARRAY,ranges,1); IplImage* gray1=cvCreateImage(cvGetSize(src1),8,1); IplImage* gray2=cvCreateImage(cvGetSize(src2),8,1); cvCvtColor(src1,gray1,CV_BGR2GRAY); cvCvtColor(src2,gray2,CV_BGR2GRAY); //vCvtColor(...),是Opencv里的颜色空间转换函数,可以实现RGB颜色向HSV,HSI等颜色空间的转换,也可以转换为灰度图像。 //参数CV_RGB2GRAY是RGB到gray, //参数CV_GRAY2RGB是gray到RGB cvCalcHist(&gray1,hist1,0,0);//统计图像在[0 255]像素的均匀分布,将统计结果存在结构体中 cvCalcHist(&gray2,hist2,0,0); //draw histogram----- //统计直方图中的最大直方块 float histMax1=0,histMax2=0; cvGetMinMaxHistValue(hist1,0,&histMax1,0); cvGetMinMaxHistValue(hist2,0,&histMax2,0); //创建一张一维直方图的“图”,横坐标为灰度级,纵坐标为像素个数 IplImage *grayHist1=cvCreateImage(cvSize(256*2,64*2),8,1); IplImage *grayHist2=cvCreateImage(cvSize(256*2,64*2),8,1); cvZero(grayHist1); cvZero(grayHist2); //分别将每个直方块的值绘制到图中 for(int i=0;i<255;i++) { float histValue=cvQueryHistValue_1D(hist1,i); float nextValue=cvQueryHistValue_1D(hist1,i+1); //计算直方块4个点的值 CvPoint pt1=cvPoint(i*2,64*2); CvPoint pt2=cvPoint((i+1)*2,64*2); CvPoint pt3=cvPoint((i+1)*2,(64-(nextValue/histMax1)*64)*2); //nextValue/histMax是将i级像素点个数归一到0~1,在*64是使其高对在0~64之间 //由于opencv图像是以左上角为坐标原点,向右为x轴,向下时y轴,而显示的直方图是向上增长的,所以用64减,将其倒过来显示 CvPoint pt4=cvPoint(i*2, (64-(histValue/histMax1)*64)*2); int ptNum=5; CvPoint pt[5]; pt[0]=pt1; pt[1]=pt2; pt[2]=pt3; pt[3]=pt4; pt[4]=pt1; cvFillConvexPoly(grayHist1,pt,ptNum,cvScalar(255)); //填充直方块 } for(int i=0;i<255;i++) { float histValue=cvQueryHistValue_1D(hist2,i); float nextValue=cvQueryHistValue_1D(hist2,i+1); //计算直方块4个点的值 CvPoint pt1=cvPoint(i*2,64*2); CvPoint pt2=cvPoint((i+1)*2,64*2); CvPoint pt3=cvPoint((i+1)*2,(64-(nextValue/histMax2)*64)*2); //nextValue/histMax是将i级像素点个数归一到0~1,在*64是使其高对在0~64之间 //由于opencv图像是以左上角为坐标原点,向右为x轴,向下时y轴,而显示的直方图是向上增长的,所以用64减,将其倒过来显示 CvPoint pt4=cvPoint(i*2, (64-(histValue/histMax2)*64)*2); int ptNum=5; CvPoint pt[5]; pt[0]=pt1; pt[1]=pt2; pt[2]=pt3; pt[3]=pt4; pt[4]=pt1; cvFillConvexPoly(grayHist2,pt,ptNum,cvScalar(255)); //填充直方块 } cvNamedWindow("grayHistogram1"); cvNamedWindow("grayHistogram2"); cvShowImage("grayHistogram1",grayHist1); cvShowImage("grayHistogram2",grayHist2); cvWaitKey(0); system("pause"); return 0; }

原图:

处理后图:

原图直方图:

均衡化后直方图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持靠谱客。

最后

以上就是高兴鞋垫最近收集整理的关于C语言实现直方图均衡化的全部内容,更多相关C语言实现直方图均衡化内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(112)

评论列表共有 0 条评论

立即
投稿
返回
顶部