看板 C_and_CPP 關於我們 聯絡資訊
開發平台(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)
firejox:我想你轉的部份有沒有寫錯呀... 05/24 19:18
VictorTom:用C寫的是對的嗎?? 如果是對的那核心轉換的邏輯應該OK, 05/24 23:20
VictorTom:(除非改code時改壞); 這樣的話, 你也許可以先試試讀檔之 05/24 23:20
VictorTom:後都先不要處理直接輸出看看結果. 話說, 原本的非亂碼但 05/24 23:21
VictorTom:圖不對是怎樣的圖?? 改前改後的code也建議用置底網站貼 05/24 23:21
VictorTom:出....@_@" 05/24 23:22
※ 編輯: Zephyr750 來自: 114.33.224.25 (05/25 19:11)
Zephyr750:code和圖都貼了! 05/25 19:12
james732:可以的話我希望你把原本的 raw 寄一個給我 XD 05/25 19:13
james732:james732@gmail.com < 把圖跟原本的C語言程式都丟過來吧 05/25 19:13
Zephyr750:丟了!謝謝!麻煩你了! 05/25 19:36
james732:我收到了,不過發現手邊沒有軟體可以開啟raw檔 orz 05/25 19:46
james732:可以的話我想看C語言版本的程式 05/25 19:47
firejox:我想知道你怎麼做 模糊的... 05/25 20:16
Zephyr750:C版本的程式呀?!不知道被我丟去哪了...我重寫好了! 05/25 20:43
firejox:你要不要把你的temp用int存... 05/25 23:24
VictorTom:你一開始把資料從fp[]讀入ifp[], 然後計算過程是這樣: 05/25 23:29
VictorTom:temp=9個ifp[]的平均, ifp[]=temp. 仔細想想看這樣子的 05/25 23:30
VictorTom:流程是不是有什麼不太對勁; 想想你的迴圈一次一次的loop 05/25 23:31
VictorTom:跑時, 上面的流程會對ifp造成什麼影響:) 05/25 23:31
Zephyr750:寄好了!c版程式會貼出來! 05/26 00:29
※ 編輯: Zephyr750 來自: 114.33.224.25 (05/26 00:32)
Zephyr750:C版程式今天剛寫,經過測試完成,圖檔也正確輸出! 05/26 00:33
VictorTom:奇怪, 核心處理的code是一樣的, 理論上C版的應該會和C++ 05/26 00:51
VictorTom:版的有一模一樣的問題才對....@_@" 05/26 00:52
Zephyr750:所以我才來問問題呀!^^ 05/26 07:14
Zephyr750:結果??還沒有解出來耶!@@ 05/26 23:07
firejox:你要不要把temp總和用迴圈或者一行一行分開 05/26 23:23
firejox:不要一直用加號串聯... 05/26 23:24
VictorTom:我有點看不懂你的意思, 你的C版OK但C++版不OK, 還是兩個 05/26 23:58
VictorTom:版本結果都不OK?_? 05/26 23:58
VictorTom:小弟我看到的問題是, 假設ifp簡化成一維array來看: 05/26 23:59
VictorTom:你做了 temp=average of ifp[1,2,3]; 然後ifp[2]=temp; 05/27 00:00
VictorTom:這樣你下一輪迴圈要算 temp=average of ifp[2,3,4]時, 05/27 00:00
VictorTom:ifp[2]已經被你改過而非原來的值了, 這樣算遇到在後方本 05/27 00:02
VictorTom:來有個銳利邊緣時, 平滑出來的結果就會變得比較異常. 05/27 00:03
VictorTom:Ex: 假設ifp[]有值: {10, 20, 0, 10, 20}; 左右兩邊不看 05/27 00:08
VictorTom:平滑結果應為{##, 10, 10, 10, ##}; 但套用你的演算法會 05/27 00:08
VictorTom:得到{##, 10, 6, 12, ##}, 結果就會看起來很奇怪@_@" 05/27 00:09
VictorTom:至於解決方法應該不難, array的操作注意一下就好XD 05/27 00:13
Zephyr750:C版OK,C++不OK 05/27 07:11
Zephyr750:你說的不影響結果!是演算法的問題,不會造成溢位的問題 05/27 07:22
將三種版本的程式 /* //將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)
VictorTom:fp還是開unsigned char[], 但是讀的時候用: 05/27 09:25
VictorTom:file.read((char*)fp, frameH*frameV); 呢?? 和C++的IO 05/27 09:25
VictorTom:函數不太熟Orz 05/27 09:26
VictorTom:剛試了一下, 上面推的應該work, 當然file.write的地方 05/27 09:38
VictorTom:也要記得掛轉型就是了XD 05/27 09:39
Zephyr750:不好意思!你是不是沒有仔細看我貼出來的code呢?(連結 05/27 22:43
Zephyr750:裡面的),你說的方法,試過了才上來問的唷!不好意思! 05/27 22:44
VictorTom:我自己找了張圖試過, 拿你原來的code跑能跑出類似的問題 05/27 23:05
VictorTom:然後修改過你的code並能跑出結果後才推文的喔@_@" 05/27 23:05
VictorTom:你說你用unsigned char*宣告fp, 這一步是對的; 05/27 23:06
VictorTom:但是也改用了 file>>fp[..]; 這一步是錯的. 05/27 23:06
VictorTom:要用原來的方式file.read()讀才對(fp傳入前要cast就是) 05/27 23:08
VictorTom:http://nopaste.info/e41919c5f5.html 改過的code. 05/27 23:12
VictorTom:或者看你方不方便upload一下你的raw檔@_@" 05/27 23:12
Zephyr750:需要星期天晚上才有辦法弄到圖了!^^"sorry! 05/27 23:21
Zephyr750:我找到.raw圖檔了!給我mail吧! 05/27 23:38
VictorTom:OK:) 所以你試過uchar *fp搭file.read()是失敗的就是?? 05/27 23:39
Zephyr750:file.read()不吃char以外的格式... 05/27 23:41
VictorTom:所以我有說要cast啊. file.read((char*)fp); 05/27 23:44
VictorTom:但fp宣告和new時還是用unsigned char* 05/27 23:45
VictorTom:試完了, 就是我說的問題, 請參考我上面貼的code link, 05/27 23:46
Zephyr750:目前手邊沒有看圖程式可以看.raw檔,暫時無法測試!^^\ 05/27 23:47
VictorTom:當然檔案大小要請你自己改回你的圖檔的size:) 05/27 23:47
Zephyr750:你測試是ok的囉? 05/27 23:47
Zephyr750:先感謝你....萬分感謝! 05/27 23:48
※ 編輯: Zephyr750 來自: 219.81.194.122 (05/27 23:50)
VictorTom:已回信附圖與code給您(code如同貼的link). 看您是否過兩 05/28 00:00
VictorTom:天有軟體的時候再試看看吧:) 05/28 00:01