Re: [問題] 關於影像二值化??
※ 引述《goodrain (mr.fu)》之銘言:
: ※ 引述《kiyasuto1 (kiy)》之銘言:
: : 各位前輩好!!小弟是用BCB作的二值化,寫了個副程式,
: : 想用圖的所有像素灰階值相加除以總像素數目來作門檻!
: : (門檻=所有像素灰階值相加/總像素數目)
: : 程式碼如下
: : void tw(Byte **a)
: : {
: : int Bsum;
: : float Background;
: : for(int i = 0; i < ImgWidth; i++)
: : {
: : for(int j = 0; j < ImgHeight; j++)
: : {
: : Background=(Bsum+=a[i][j])/((ImgHeight)*(ImgWidth));
: : }
: : }
其實 kiyasuto1 這段最後結果,Background 和
goodrain 的 Background 結果是一樣的。
先看一下下面這段程式碼
#include <stdio.h>
int main()
{
int a=1, b=5, c=2, d=0;
printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
d = (a+=b)/c;
printf("a=%d, b=%d, c=%d, d=%d\n", a, b, c, d);
return 0;
}
實際上 d=(a+=b) / c ; 它是分解成
a=a+b;
d=a/c;
兩個步驟寫成一行而已, 輸出結果會是
a=1, b=5, c=2, d=0
a=6, b=5, c=2, d=3
於是 kiyasuto1 的這行
Background=(Bsum+=a[i][j])/((ImgHeight)*(ImgWidth));
也就只相等於下面這兩行而已
Bsum+= a[i][j];
Background = Bsum / ((ImgHeight)*(ImgWidth)) ;
整段看下來的話,除了做了沒必要的除法運算外,和 goodrain 的結果其實是一樣的。
意思是,「以最小修改」為目的的話,原原原 po(kiyasuto1) 程式碼只要改這樣即可
for(int i = 0; i < ImgWidth; i++)
{
for(int j = 0; j < ImgHeight; j++)
{
Background=(float)(Bsum+=a[i][j])/((ImgHeight)*(ImgWidth));
}
}
只是這樣的確效率不太好,因要算平均的話,其實只要在算完總合時再除以點數即可,
所以loop 裡不必放除法,只要做加法動作即可,於是一般就像 goodrain 之作法。
: 這一段改成
: for(int i = 0; i < ImgWidth; i++)
: {
: for(int j = 0; j < ImgHeight; j++)
: {
: Bsum+=a[i][j];
: }
: }
: Background= (float)Bsum /(ImgHeight)*(ImgWidth);
以下恕刪。
Background 可以用 float 或 double 都沒問題,
但 Bsum 不建議用 float , 「至少」用 double,可以試試下面這個程式
#include <stdio.h>
int main()
{
float f=1.23456789E9f;
double d=1.23456789E9;
unsigned u=123456789;
printf("f=%.16e\nd=%.16e\nu=%u\n", f, d, u);
f=f+1.0f, d=d+1.0, u=u+1;
printf("f=%.16e\nd=%.16e\nu=%u\n", f, d, u);
return 0;
}
上面加 1 有影響的,只有 d 和 u 而已,這是因浮點數機制問題,
有興趣的話該去 K IEEE754 spec , 及浮點數 + - * / 大概是怎麼做的。
---
另,我有個嚴重的疑惑,system 若含 FPU ,其實 double 速度都比 float 快,
精度也比 float 高,為何還堅持要用 float ?
是因一些顯卡裡之 FPU 用 float 較快嗎?
--
No matter how gifted you are,
alone, can not change the world.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
推
10/06 02:06, , 1F
10/06 02:06, 1F
已修改, 謝謝意見 *^_^*
→
10/06 02:06, , 2F
10/06 02:06, 2F
推
10/06 02:08, , 3F
10/06 02:08, 3F
→
10/06 02:09, , 4F
10/06 02:09, 4F
推
10/06 02:13, , 5F
10/06 02:13, 5F
→
10/06 02:13, , 6F
10/06 02:13, 6F
→
10/06 02:13, , 7F
10/06 02:13, 7F
→ ericinttu:我計組忘光光,留給高手回答好了. (退後十大步 XD) 10/06 02:13
→
10/06 02:13, , 8F
10/06 02:13, 8F
→
10/06 02:14, , 9F
10/06 02:14, 9F
→
10/06 02:15, , 10F
10/06 02:15, 10F
→
10/06 02:14, , 11F
10/06 02:14, 11F
→
10/06 02:19, , 12F
10/06 02:19, 12F
補齊。 另請教 akasan, 在該 code 裡
float f=1.0f;
while(1.0f+f!=1.0f) f/=2.0f;
以我系統裡,正常 f 為 1.192092896e-07F (FLT_EPSILON)時跳出 while loop
這樣就算 printf 出來也不該是 DBL_EPSILON , 所以才判斷有偷轉,
應可這麼解讀吧?
※ 編輯: tropical72 來自: 180.177.78.41 (10/06 02:32)
推
10/06 03:01, , 13F
10/06 03:01, 13F
→
10/06 03:02, , 14F
10/06 03:02, 14F
→
10/06 03:07, , 15F
10/06 03:07, 15F
→
10/06 03:10, , 16F
10/06 03:10, 16F
推
10/06 06:23, , 17F
10/06 06:23, 17F
→
10/06 06:24, , 18F
10/06 06:24, 18F
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章