近来接触图像处理领域,opencv入门之后,想自己动手实现一些算法,先从直方图均衡化开始吧!
我使用的图像文件是只包含数据yuv格式图像,以后等需要的时候再处理从普通格式(jpg、png等)提取rgb或者yuv数据的过程。
首先获取一副yuv格式图像,如果不明白yuv格式内部数据的存储方式,可自行百度。先上处理效果。
处理前:
处理后:
直方图本身不具有去燥功能,只是增加了对比度,使图像看起来更清晰,配合上一副高斯滤波后的图像就看的舒服点了。
直方图均衡+高斯滤波后的效果:
效果还是可以的,只需要再进行一些细节优化,在尽量不损失图像细节的情况下,可以得到很好的效果。
代码:
#include <iostream>
#define IMAGE_WIDTH 1920
#define IMAGE_HEIGHT 1080
int main()
{
unsigned char* inputImage = NULL;
unsigned char* outputImage = NULL;
FILE *_uv = fopen("D:/test/3_noise.yuv", "r");
if (!_uv) {
printf("Can not open image\n");
return 0;
}
fseek(_uv, 0L, SEEK_END);
long len = ftell(_uv);
fseek(_uv, 0L, SEEK_SET);
inputImage = (unsigned char*)malloc(len);
outputImage = (unsigned char*)malloc(len);
fread(inputImage, 1, len, _uv);
fclose(_uv);
memcpy(outputImage, inputImage, len);
int pixCount[256] = { 0 }; //统计各个像素出现的次数
float prob[256] = { 0.0 }; //统计各个像素出现概率
//只处理Y分量,以下同理
for (size_t i = 0; i < (IMAGE_WIDTH * IMAGE_HEIGHT); i++)
{
if (inputImage[i] >= 0 && inputImage[i] <= 256)
pixCount[inputImage[i]]++;
}
for (size_t i = 0; i < 256; i++)
{
prob[i] = pixCount[i] / (IMAGE_WIDTH * IMAGE_HEIGHT);
}
int newPixCount[256] = { 0 };
float sum = 0;
//计算新的像素值
for (size_t i = 0; i < 256; i++)
{
sum += prob[i];
newPixCount[i] = (sum*255.0 + 0.5);
}
for (size_t i = 0; i < (IMAGE_HEIGHT*IMAGE_WIDTH); i++)
{
if (inputImage[i] >= 0 && inputImage[i] < 256)
{
outputImage[i] = newPixCount[inputImage[i]];
}
}
_uv = fopen("D:/test/filter.yuv", "wb");
if (_uv) {
int r = fwrite(outputImage, 1, len, _uv);
fflush(_uv);
fclose(_uv);
}
free(inputImage);
free(outputImage);
return 0;
}
不明白直方图均衡原理的可以去这个链接看看:直方图均衡解释
此文章中暂时不涉及高斯滤波等去燥操作,有心学习的需要自行百度。我打算也以博客的形式后续发出!
有需求yuv格式图片可以去下面下载(百度网盘链接不包含yuv格式图片播放器,CSDN资源里包含yuv格式播放器,yuv格式播放器可以自行百度下载):
百度网盘链接: 百度网盘链接 提取码: w3af
CSDN链接: CSDN链接
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)