推 LPH66:看這描述似乎是 memory leak... 05/21 02:37
是說記憶體釋放問題嗎@@?
可是我的確沒有要釋放讀取到的圖片
→ azureblaze:11.7MB是有壓縮的的結果 要顯示一定要解壓縮 05/21 08:28
→ azureblaze:所以用掉376M是正確的 05/21 08:29
我了解了,謝謝解說
推 chchwy:32bit程式不能用超過2G的記憶體,這是 Windows 的規定 05/21 08:34
所以最高最高就只能用到2G嗎@@
怪了...總覺得以前用XP 32位元時,玩遊戲時很容易就超過2G的說@@
還是真的是我記錯了
→ azureblaze:然後"剩下800M"和 "還有一塊完整超過376M"是兩回事 05/21 08:51
所以說剩下800M都是分散的,因此沒有一塊完整376M的記憶體空間,所以才會當嗎
可是我程式讀取的圖片,每一張大約都會耗掉39M的記憶體
這樣的話只能讀取到1.2G的記憶體不是也怪怪的嗎@@
剩下的800M感覺沒有一個區塊是完整的39M挺怪的
推 a27417332:然後工作管理員看到的和指標定址空間也是兩回事吧 05/21 09:08
就像上面說的,是因為沒有完整的記憶體位置,所以才沒辦法讀取嚕@@
----------------
謝謝各位的解說,所以真的沒有其他辦法了嗎
※ 編輯: googled (49.158.60.5), 05/21/2014 11:20:42
→ Chikei:楚(像是為何不釋放?)讓大家幫你想想合理的設計吧。 05/21 12:31
→ pcyu16:硬體跟OS 對程式來說都算先天限制吧.. 05/21 12:39
→ pcyu16:不管是什麼介面 應該都沒必要同時存這麼多圖片在記憶體? 05/21 12:40
→ pcyu16:還有就是這隻程式如果有現在以外的機器要用 怎麼辦...? 05/21 12:42
好的,其實聽你們這樣說也是,是我管理記憶體太差,
我這程式瀏覽圖片時有三種大小可以切換,分別是大張模式、中張模式、小張模式
大張模式一次顯示1張,中張是一次顯示6張,小張一次顯示36張
所以我程式一開始讀取圖片會縮放到大張模式該有的大小並丟進Vector(SourceImg)保存,
然後釋放原始圖片的記憶體
接著再看說使用者是用哪一種模式瀏覽照片,再從該SourceImg取出後縮放到符合的大小
所以這就是我會吃記憶體吃很兇的關係
本來是想說或許可以改成說需要用到哪些圖片,在臨時去開啟檔案就好,
沒有必要每張圖片都保存。
但我這程式可以提供修圖,像是R、G、B調整等等,
因此我另外又有一個Vector(ProcessImg)是儲存處理好的圖片
所以這就是我不釋放的原因,因為如果每次都把processImg跟SourceImg都釋放
要用到時才開檔並縮放,接著去處理像素,這樣會讓使用者等太久@@
而如果我不釋放的話,假設我現在在中張模式的第五頁,要顯示第30~36張的照片
就可以直接從ProcessImg取出第30~36張的照片並顯示,不需要讓使用者等待
而如果我要把第31張的照片拿來修圖,只需要從SourceImg取出第31張照片,
處理完像素後覆蓋到ProcessImg第31張的位置就可以了
這是我程式大概的流程,不曉得是不是有不妥的地方,拜託各位指導一下了
謝謝
※ 編輯: googled (49.158.60.5), 05/21/2014 13:27:21
→ blackwindy:你OS沒修好 05/21 13:11
其實真的滿後悔沒有認真修作業系統的...
推 donkeychen:(本人對影像處理不太熟) 不知道有沒有相關 05/21 14:34
→ donkeychen:那個轉換好像是在影像處理時用的 對於不處理儲存是否能 05/21 14:41
→ donkeychen:節省空間使用我不太知道 給個參考 希望有幫助 05/21 14:42
謝謝你的提供,所以是說我可以使用類似這種演算法來轉算接著再改圖
而不是像我每次使用者修圖時都是跑雙迴圈跑完所有的像素嚕@@
我都是用
for(int i=0 ; i < img.width() ; ++i)
for(int j=0 ; j < img.height() ; ++j){
//處理圖片
}
所以影像處理的速度都沒很快@@
※ 編輯: googled (49.158.60.5), 05/21/2014 15:37:28
→ googled:查了一下影像處理的效率,似乎轉成char好像比較快@@ 05/21 17:44
→ googled:來寫個測試的程式看看 05/21 17:44
推 LiloHuang:處理圖片的雙重迴圈,請先跑 height 再跑 width 會較佳 05/21 18:20
想請問一下為什麼先跑height會比較佳呢?
是因為照片都是橫的(width > height)較多的關係嗎?
→ LiloHuang:如果要更快可以每次處理 32bit,或者用 SIMD Intrinsic 05/21 18:23
不好意思...小弟愚昧,請問什麼是每次處理32Bit跟SIMD Intrinsic是什麼意思?
推 LiloHuang:另外之前有貼過的連結,我再分享一次給你參考 05/21 18:25
→ LiloHuang:搭配下 debug break point 來幫助自己釐清哪些階段增加 05/21 18:25
謝謝你,這軟體真的好用,還額外發現它可以抓出程式用了哪些DLL
不然我以前都還要把Qt的DLL一個個找出來測試
→ LiloHuang:真正要快就是用 OpenCL 或者 CUDA 來跑你的演算法 05/21 18:32
推 LiloHuang:這就是 row major 讀取的好處,跟先跑 height 目的一樣 05/21 20:04
原來如此,謝謝你的解說
→ LiloHuang:假設你一個 pixel 就是 32bit 的話,每次就抓 32bit 05/21 20:06
→ LiloHuang:RGBA8888 轉 BGRA8888,抓 32bit 後再用 bitwise 操作 05/21 20:07
請問用bitwise是不是跟操作uchar差不多@@?
昨天在網路上查到說用uchar可以加速QImage的處理速度
但是翻到QT的文檔又說不建議大家用uchar來操作,似乎是不安全的樣子
但換成bitwise來操作不知道有沒有這問題@@
(雖然本身也沒用過bitwise來改像素,還要在查查ˇ_ˇ)
QT文檔是說:
Warning: If you are accessing 32-bpp image data, cast the returned pointer to
QRgb* (QRgb has a 32-bit size) and use it to read/write the pixel value. You
cannot use the uchar* pointer directly, because the pixel format depends on
the byte order on the underlying platform. Use qRed(), qGreen(), qBlue(), and
qAlpha() to access the pixels.
→ LiloHuang:SIMD 操作使用 MMX (64bit), SSE (128bit) 的 CPU 指令 05/21 20:10
→ LiloHuang:寫 Intrinsic 的好處是,是指 #include <xmmintrin.h> 05/21 20:11
→ LiloHuang:來操作那些 SIMD 的指令,而不用自己寫 inline assembly 05/21 20:12
→ LiloHuang:至於是不是要把資料從"空間域"轉"頻率域",要看問題類型 05/21 20:14
→ LiloHuang:影像處理有些細節要注意,row major 存取,記憶體對齊 05/21 20:17
→ LiloHuang:可以再上網多多查一些資料,大概如此。 05/21 20:18
推 LiloHuang:先跑 height 就是 row major 讀取,資料就是這樣擺放的 05/21 20:20
→ LiloHuang:這種存取方式可以有效的利用 cache,甚至做 prefetch 05/21 20:25
SIMD感覺難度好大ˇ_ˇ
果然自己不懂的地方還是好多,我今天在查說把Qt跟openCV結合
很多人都說openCV有優化過,所以速度絕對會比較快
就想把影像的部分都改成openCV來操作,但等於又要從0學習了
不過真的很謝謝你
※ 編輯: googled (49.159.8.95), 05/22/2014 21:18:13
推 LiloHuang:OpenCV是個好選擇,要快可再搭配 Intel IPP,加油囉 :D 05/22 21:49
推 donkeychen:推LiloHuang大大 (y) 06/05 13:54