數字圖像處理(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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章