[解決] C++讀.raw灰階圖檔

看板C_and_CPP (C/C++)作者 (紅蓮西風750)時間15年前 (2011/05/23 22:47), 編輯推噓10(10057)
留言67則, 4人參與, 最新討論串1/1
開發平台(Platform):Visual C++ 2005 問題(Question):檔案輸出不正確(不是我想要的Smoothing) 餵入的資料(Input):a.raw(一張FullHD無檔頭的灰階點陣圖) 預期的正確結果(Expected Output):ba.raw(a.raw的模糊影像) 原圖 http://www.wretch.cc/album/show.php?i=darkblack&b=33&f=1788349860&p=1 錯誤結果(Wrong Output): 使用C語言的版本是使用unsigned char儲存0-255的資料 C版程式 http://codepad.org/NuSax7x1 使用FILE指標把資料放進陣列中 但是在C++不知道怎麼將資料正確的放進陣列中 程式可以執行!但是輸出圖檔是錯誤的! 用 file.read() 和 ofile.write()但是它只吃char http://codepad.org/rbV5jue0 不過輸出的圖檔效果是最接近預想的模糊圖形!不會是亂到不行的亂碼! http://www.wretch.cc/album/show.php?i=darkblack&b=33&f=1788349859&p=0 因為資料型態不是unsigned char所以,我猜會造成溢位!改了資料型態! 後來再改語法 把 file.read() 改成 file >> 把ofile.write()改成ofile << 但是依然不對!圖檔變成亂碼! 就不知道問題出在哪了! 程式碼(Code):(請善用置底文網頁, 記得排版) #include<iostream> #include<fstream> using namespace std; #define frameH 1920 #define frameV 1080 int main() { unsigned char *fp = new unsigned char [frameH*frameV]; fstream file; file.open("a.raw", fstream::in | fstream::binary); if( !file.good()) cout << "file讀檔失敗" << endl; for(int i = 0 ; i < frameH ; ++i){ for(int j = 0 ; j < frameV ; ++j){ file >> *(fp+(i+j*frameH)); }} file.close(); unsigned int *ifp = new unsigned int [frameH*frameV]; for(int i = 0 ; i < frameH ; ++i){ for(int j = 0 ; j < frameV ; ++j){ *(ifp+i+j*frameH) = *(fp+i+j*frameH); }} double temp; for(int i = 1 ; i < frameH-1 ; ++i){ for(int j = 1 ; j < frameV-1 ; ++j){ temp = *(ifp + (i-1) + (j-1)* frameH) + *(ifp + i + (j-1)* frameH) + *(ifp + (i+1) + (j-1)* frameH) + *(ifp + (i-1) + j * frameH) + *(ifp + i + j * frameH) + *(ifp + (i+1) + j * frameH) + *(ifp + (i-1) + (j+1)* frameH) + *(ifp + i + (j+1)* frameH) + *(ifp + (i+1) + (j+1)* frameH); *(ifp+i+j*frameH) = (temp /9); }} for(int i = 0 ; i < frameH ; ++i){ for(int j = 0 ; j < frameV ; ++j){ *(fp+i+j*frameH) = *(ifp+i+j*frameH); }} fstream ofile; ofile.open("ba.raw", fstream::out | fstream::binary); if( !ofile.good()) cout << "ofile讀檔失敗" << endl; for(int i = 0 ; i < frameH ; ++i){ for(int j = 0 ; j < frameV ; ++j){ ofile << *(fp+(i+j*frameH)); }} ofile.close(); delete [] fp; delete [] ifp; system("PAUSE"); return 0; } 補充說明(Supplement): 用C寫過一次!為了練習C++而練習的習作! 最後解出來: → VictorTom:要用原來的方式file.read()讀才對(fp傳入前要cast就是) 05/27 23:08 → VictorTom:http://nopaste.info/e41919c5f5.html 改過的code. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.33.224.25 ※ 編輯: Zephyr750 來自: 114.33.224.25 (05/24 19:14) ※ 編輯: Zephyr750 來自: 114.33.224.25 (05/24 19:18)

05/24 19:18, , 1F
我想你轉的部份有沒有寫錯呀...
05/24 19:18, 1F

05/24 23:20, , 2F
用C寫的是對的嗎?? 如果是對的那核心轉換的邏輯應該OK,
05/24 23:20, 2F

05/24 23:20, , 3F
(除非改code時改壞); 這樣的話, 你也許可以先試試讀檔之
05/24 23:20, 3F

05/24 23:21, , 4F
後都先不要處理直接輸出看看結果. 話說, 原本的非亂碼但
05/24 23:21, 4F

05/24 23:21, , 5F
圖不對是怎樣的圖?? 改前改後的code也建議用置底網站貼
05/24 23:21, 5F

05/24 23:22, , 6F
出....@_@"
05/24 23:22, 6F
※ 編輯: Zephyr750 來自: 114.33.224.25 (05/25 19:11)

05/25 19:12, , 7F
code和圖都貼了!
05/25 19:12, 7F

05/25 19:13, , 8F
可以的話我希望你把原本的 raw 寄一個給我 XD
05/25 19:13, 8F

05/25 19:13, , 9F
james732@gmail.com < 把圖跟原本的C語言程式都丟過來吧
05/25 19:13, 9F

05/25 19:36, , 10F
丟了!謝謝!麻煩你了!
05/25 19:36, 10F

05/25 19:46, , 11F
我收到了,不過發現手邊沒有軟體可以開啟raw檔 orz
05/25 19:46, 11F

05/25 19:47, , 12F
可以的話我想看C語言版本的程式
05/25 19:47, 12F

05/25 20:16, , 13F
我想知道你怎麼做 模糊的...
05/25 20:16, 13F

05/25 20:43, , 14F
C版本的程式呀?!不知道被我丟去哪了...我重寫好了!
05/25 20:43, 14F

05/25 23:24, , 15F
你要不要把你的temp用int存...
05/25 23:24, 15F

05/25 23:29, , 16F
你一開始把資料從fp[]讀入ifp[], 然後計算過程是這樣:
05/25 23:29, 16F

05/25 23:30, , 17F
temp=9個ifp[]的平均, ifp[]=temp. 仔細想想看這樣子的
05/25 23:30, 17F

05/25 23:31, , 18F
流程是不是有什麼不太對勁; 想想你的迴圈一次一次的loop
05/25 23:31, 18F

05/25 23:31, , 19F
跑時, 上面的流程會對ifp造成什麼影響:)
05/25 23:31, 19F

05/26 00:29, , 20F
寄好了!c版程式會貼出來!
05/26 00:29, 20F
※ 編輯: Zephyr750 來自: 114.33.224.25 (05/26 00:32)

05/26 00:33, , 21F
C版程式今天剛寫,經過測試完成,圖檔也正確輸出!
05/26 00:33, 21F

05/26 00:51, , 22F
奇怪, 核心處理的code是一樣的, 理論上C版的應該會和C++
05/26 00:51, 22F

05/26 00:52, , 23F
版的有一模一樣的問題才對....@_@"
05/26 00:52, 23F

05/26 07:14, , 24F
所以我才來問問題呀!^^
05/26 07:14, 24F

05/26 23:07, , 25F
結果??還沒有解出來耶!@@
05/26 23:07, 25F

05/26 23:23, , 26F
你要不要把temp總和用迴圈或者一行一行分開
05/26 23:23, 26F

05/26 23:24, , 27F
不要一直用加號串聯...
05/26 23:24, 27F

05/26 23:58, , 28F
我有點看不懂你的意思, 你的C版OK但C++版不OK, 還是兩個
05/26 23:58, 28F

05/26 23:58, , 29F
版本結果都不OK?_?
05/26 23:58, 29F

05/26 23:59, , 30F
小弟我看到的問題是, 假設ifp簡化成一維array來看:
05/26 23:59, 30F

05/27 00:00, , 31F
你做了 temp=average of ifp[1,2,3]; 然後ifp[2]=temp;
05/27 00:00, 31F

05/27 00:00, , 32F
這樣你下一輪迴圈要算 temp=average of ifp[2,3,4]時,
05/27 00:00, 32F

05/27 00:02, , 33F
ifp[2]已經被你改過而非原來的值了, 這樣算遇到在後方本
05/27 00:02, 33F

05/27 00:03, , 34F
來有個銳利邊緣時, 平滑出來的結果就會變得比較異常.
05/27 00:03, 34F

05/27 00:08, , 35F
Ex: 假設ifp[]有值: {10, 20, 0, 10, 20}; 左右兩邊不看
05/27 00:08, 35F

05/27 00:08, , 36F
平滑結果應為{##, 10, 10, 10, ##}; 但套用你的演算法會
05/27 00:08, 36F

05/27 00:09, , 37F
得到{##, 10, 6, 12, ##}, 結果就會看起來很奇怪@_@"
05/27 00:09, 37F

05/27 00:13, , 38F
至於解決方法應該不難, array的操作注意一下就好XD
05/27 00:13, 38F

05/27 07:11, , 39F
C版OK,C++不OK
05/27 07:11, 39F

05/27 07:22, , 40F
你說的不影響結果!是演算法的問題,不會造成溢位的問題
05/27 07:22, 40F
將三種版本的程式 /* //將fp轉ifp取消 for(int i = 0 ; i < frameH ; ++i){ for(int j = 0 ; j < frameV ; ++j){ *(ifp+i+j*frameH) = *(fp+i+j*frameH); }} */ int temp; for(int i = 1 ; i < frameH-1 ; ++i){ for(int j = 1 ; j < frameV-1 ; ++j){ temp = //原本讀寫ifp,改成讀fp寫入ifp *(fp + (i-1) + (j-1) * frameH) + *(fp + i + (j-1) * frameH) + *(fp + (i+1) + (j-1) *frameH) + *(fp + (i-1) + j * frameH) + *(fp + i + j * frameH) + *(fp + (i+1) + j *frameH) + *(fp + (i-1) + (j+1)* frameH) + *(fp + i + (j+1)* frameH) + *(fp + (i+1) + (j+1)*frameH) ; *(ifp+i+j*frameH) = (temp /9); }} 就算是這樣,程式結果(圖有沒有問題)依然不會有任何影響 smoothign演算法應該會有影響,不過,不是大問題 ※ 編輯: Zephyr750 來自: 114.33.224.25 (05/27 07:27)

05/27 09:25, , 41F
fp還是開unsigned char[], 但是讀的時候用:
05/27 09:25, 41F

05/27 09:25, , 42F
file.read((char*)fp, frameH*frameV); 呢?? 和C++的IO
05/27 09:25, 42F

05/27 09:26, , 43F
函數不太熟Orz
05/27 09:26, 43F

05/27 09:38, , 44F
剛試了一下, 上面推的應該work, 當然file.write的地方
05/27 09:38, 44F

05/27 09:39, , 45F
也要記得掛轉型就是了XD
05/27 09:39, 45F

05/27 22:43, , 46F
不好意思!你是不是沒有仔細看我貼出來的code呢?(連結
05/27 22:43, 46F

05/27 22:44, , 47F
裡面的),你說的方法,試過了才上來問的唷!不好意思!
05/27 22:44, 47F

05/27 23:05, , 48F
我自己找了張圖試過, 拿你原來的code跑能跑出類似的問題
05/27 23:05, 48F

05/27 23:05, , 49F
然後修改過你的code並能跑出結果後才推文的喔@_@"
05/27 23:05, 49F

05/27 23:06, , 50F
你說你用unsigned char*宣告fp, 這一步是對的;
05/27 23:06, 50F

05/27 23:06, , 51F
但是也改用了 file>>fp[..]; 這一步是錯的.
05/27 23:06, 51F

05/27 23:08, , 52F
要用原來的方式file.read()讀才對(fp傳入前要cast就是)
05/27 23:08, 52F

05/27 23:12, , 53F
05/27 23:12, 53F

05/27 23:12, , 54F
或者看你方不方便upload一下你的raw檔@_@"
05/27 23:12, 54F

05/27 23:21, , 55F
需要星期天晚上才有辦法弄到圖了!^^"sorry!
05/27 23:21, 55F

05/27 23:38, , 56F
我找到.raw圖檔了!給我mail吧!
05/27 23:38, 56F

05/27 23:39, , 57F
OK:) 所以你試過uchar *fp搭file.read()是失敗的就是??
05/27 23:39, 57F

05/27 23:41, , 58F
file.read()不吃char以外的格式...
05/27 23:41, 58F

05/27 23:44, , 59F
所以我有說要cast啊. file.read((char*)fp);
05/27 23:44, 59F

05/27 23:45, , 60F
但fp宣告和new時還是用unsigned char*
05/27 23:45, 60F

05/27 23:46, , 61F
試完了, 就是我說的問題, 請參考我上面貼的code link,
05/27 23:46, 61F

05/27 23:47, , 62F
目前手邊沒有看圖程式可以看.raw檔,暫時無法測試!^^\
05/27 23:47, 62F

05/27 23:47, , 63F
當然檔案大小要請你自己改回你的圖檔的size:)
05/27 23:47, 63F

05/27 23:47, , 64F
你測試是ok的囉?
05/27 23:47, 64F

05/27 23:48, , 65F
先感謝你....萬分感謝!
05/27 23:48, 65F
※ 編輯: Zephyr750 來自: 219.81.194.122 (05/27 23:50)

05/28 00:00, , 66F
已回信附圖與code給您(code如同貼的link). 看您是否過兩
05/28 00:00, 66F

05/28 00:01, , 67F
天有軟體的時候再試看看吧:)
05/28 00:01, 67F
文章代碼(AID): #1DsdEMwp (C_and_CPP)
文章代碼(AID): #1DsdEMwp (C_and_CPP)