数字图像处理(5):幂次变换(C语言实现)
幂次变换
幂次变换,点运算的一种,运算公式为s=crγ,其中,c和γ是正常数。
当γ<1,此时扩展低灰度级,压缩高灰度级,在正比函数上方,使图像变亮;
当γ>1,此时扩展高灰度级,压缩低灰度级,在正比函数下方,使图像变暗。
核磁共振图像
是利用核磁共振(nuclear magnetic resonance,简称NMR)原理,依据所释放的能量在物质内部不同结构环境中不同的衰减,通过外加梯度磁场检测所发射出的电磁波,即可得知构成这一物体原子核的位置和种类,据此可以绘制成物体内部的结构图像。
本图像来源翰·霍普金斯大学Elliot Fishman博士和Karen Horton博士的教学案例和图片。图像大小为455*600,8位灰度图像。为了增强本次实验效果,将此图像人为的进行了亮度调低。
亮度调低
代码实现
平台:vs2015
语言:C语言
流程:
1)读取图片
2)对每个像素进行幂次计算
3)输出处理后的图片
4)改变γ的值,重复上述流程
关键代码:
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
temp = c * pow( Pic[i][j]/255.0 , v )*255;
Pic[i][j] = (char)temp;
}
}
处理结果:
分析:
如幂次变换特点——当γ<1,此时扩展低灰度级,压缩高灰度级,使图像变亮;当γ>1,此时扩展高灰度级,压缩低灰度级,使图像变暗。
感觉在γ为0.4时相比于0.6的一些细节更清晰一些,当γ为0.2时图片有点过亮,一些细节反而不容易观察。
而当γ大于1时,原本就比较暗的图像变得更暗,基本上无法观察了。
另外,还测试了γ分别为0.1,0.2,0.3,0.4……0.9的结果,发现确实可以通过幂律变换实现亮暗度变化的对比度增强。
遇到问题
最初写代码直接带入公式,代码写成了如下:
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
temp = c * pow( Pic[i][j] , v );
Pic[i][j] = (char)temp;
}
}
即直接按照公式s=crγ进行带入计算。结果当γ=0.6时,得到的结果如下:
图像反而变暗了,显然这是不对的。看了一下那些曲线明白了这个公式的含义,修改为:
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
temp = c * pow( Pic[i][j]/255 , v )*255;
Pic[i][j] = (char)temp;
}
}
这样运行后反而成了一片黑了,也就是所有像素值为0。发现忽略了Pic[i][j]/255并不是浮点运算,得到的结果必然为0。于是将255改为255.0,解决问题。
附代码:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define height 600
#define width 455
typedef unsigned char BYTE; // 定义BYTE类型,占1个字节
//s = cr v
int c = 1;
float v = 0.6;
float temp;
int main(void)
{
FILE *fp = NULL;
BYTE *ptr;
BYTE **Pic = new BYTE *[height];
for (int i = 0; i != height; ++i)
{
Pic[i] = new BYTE[width];
}
int i, j;
fp = fopen("untitled.raw", "rb");
ptr = (BYTE*)malloc(width * height * sizeof(BYTE));//创建内存
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
fread(ptr, 1, 1, fp);
Pic[i][j] = *ptr; // 把图像输入到2维数组中,变成矩阵型式
ptr++;
}
}
fclose(fp);
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
temp = c * pow( Pic[i][j]/255.0 , v )*255;
Pic[i][j] = (char)temp;
}
}
fp = fopen("output.raw", "wb");
for (i = 0; i < height; i++)
{
for (j = 0; j < width; j++)
{
fwrite(&Pic[i][j], 1, 1, fp);
}
}
fclose(fp);
return 0;
}
上一篇: Unity2D声音控制面板Demo
下一篇: 50行Python代码绘制满天星