2007-05-03

我也來貢獻GPL程式

由於研究的需要,我需要找一個看圖軟體來增加裏面的演算法,之前曾想過用拿gimp來用,但gimp太大,光是看懂要改得動裏面的程式碼就不知道要花多久時間,後來想到我目前用的看圖軟體gqview,gqview是不錯,只是似乎它本身沒有存檔的功能,而存檔功能是我一定需要的。後來嘗試改 xv,還蠻順利的,xv程式碼並不會太難懂,改起來也還算方便。

我目前在我的這一版xv上面共實作了5個演算法,三個邊偵測,二個膚色偵測,這些演算法實作上去之後,對以後實驗有很大幫助。由於xv是GPL,所以我也把我改過的xv也放到網路上來,有興趣的人可以到這裏下載。

簡介一下我加上去的演算法:

下面這一張是原圖:
下面這一張是Sobel mask:
下面這一張是膚色偵測:
下面這一張是另一個膚色偵測演算法:
下面這一張是prewitt mask:
膚色偵測其實有不同的演算法,我沒有把實作那一個膚色偵測演算法的公式寫出來其實還不夠,不過,這裏很難放上LaTex的排版文字,我想,就留給有興趣的朋友再去 trace 程式碼了。

另外,這幾個演算法都有加上 hot-key,可以在主畫面的algorithm按鈕中看到,方便我自已實驗用。

我放上來的另一個目的是備份這份程式碼,因此也會不定期更新,有更新,就自然而然會把舊版殺掉,因此若是有需要的朋友點了link後找不到的話,就自已到http://www.csie.ncu.edu.tw/~955302027來找吧。

8 comments:

shin said...

你好
我目前是大四學生
想請教您的prewitt的演算法
是如何寫成的
我目前有找到prewitt的遮罩
但是我不知道該如何使用它
我的即時通是svnzkimo
MSN是svnzkimo@yahoo.com.tw
希望你能指點我一下
謝謝

Neo said...

詳細的方法還是得請你去看程式裏面的實作,我有把我改過的整個xv程式放在網路上,你可以下載去使用。

我程式裏面處理mask分二種方式做,一種是自已寫的,就是像下面這段程式碼這樣處理,這程式碼在xvneo.c裏面你可以找到,另外一種處理方式是套用xv程式處理mask的方式,我只是把mask的值填上去而已。二種方式你參考看看。



#include "xv.h"

int neoMaskPrewitt(byte *pp, int h, int w){
int i;
int j;
double mask[3][3] = {{-1, 0, 1}, {-1, 0, 1}, {-1, 0, 1}};

byte ip[w][h];
byte op[w][h];

for (i = 0; i < h; i++){
for(j = 0; j < w; j++){
if (i != 0 && i != h-1 && j != 0 && j != w-1){
op[j][i] = ip[j-1][i-1] * mask[0][0] + ip[j][i-1] * mask[0][1] + ip[j+1][i-1] * mask[0][2] +
ip[j-1][i] * mask[1][0] + ip[j][i] * mask[1][1] + ip[j+1][i] * mask[1][2] +
ip[j-1][i+1] * mask[2][0] + ip[j][i+1] * mask[2][1] + ip[j+1][i+1] * mask[2][2];
}
}
}

return 0;
}

shin said...

你好
其實我有些還不是很了解
我是用c#來編輯
有些還不是很了解
可以指導我一下嗎

我有把圖片的pixel取出來
也與遮罩相乘
然後相加起來取代原來的圖片pixel
但是圖片如果是BMP的
應該有R.G.B三種顏色
我不知道該怎麼處理
是RGB相加起來除以3嗎?

還是我有些地方沒有做出來
才會讓我的圖片有問題?

Neo said...

pixel跟mask做計算時,是一起計算的。pixel會有RGB值,假設是{255,255,255},在表示的時候其實是65536*255+256*255+255表示,因此與mask做運算時,也是以這個值下去與mask做運用,不是分別用 RGB 去計算。

shin said...

不太懂你的意思
還是我問的方式不對
為什麼要乘65536和256?

我目前
是將每個pixel的R值取出來與遮罩相乘
每個pixel的G值取出來與遮罩相乘
每個pixel的B值取出來與遮罩相乘

這樣會得到三個值
再將這3個值取代原先R.G.B的值
這樣做是對的嗎?

有的時候會有負值,也會超過255
這樣都是正常現象嗎?

Neo said...

每個pixel雖然有RGB三個值,但pixel在表示時,還是以一個單一的值在表示。假設你的pixel是以24bits,就是從0x000000變化到0xffffff,其中,前面2個f是R,中間2個f是G,後面2個f是B,因此你個別的RGB值要分別乘一個數才能讓它變化為一個單一值表示,這也是為什麼要分別乘65536及256的原因。

你的方法應該只差一個地方就對了,就是與mask做運算時,是以pixel的值與mask運算,不是RGB分開運算。

shin said...

謝謝你的幫忙
這個問題已經處理了
還有一個問題想要可以請教您嗎

目前想要做直方圖等化的處理
是將灰階圖片做直方圖等化處理
我將圖片的各個灰階度個別累加起來
分別除以圖片總像素點數得到機率值
然後再將這些機率值以"目前項=前面項相加"
這樣就會得到新的機率值
再將這些機率值乘255

理論上這樣的處理
應該會使得背景和主題的差異度更明顯

如果您會
可以麻煩您指導一下
感激不盡

Neo said...

我不是很清楚你的描述,你可以給我一張原圖跟一張處理過後的圖嗎?這樣或許我就可以了解你想做的效果。