2011-12-17 64 views
3

顯示我使用下列程序,以顯示MFC查看OpenCV的墊。而且它對於未被複制的圖像效果很好。但對於裁剪預圖像,它顯示了空白或怪異圖像像下面的那些:OpenCV的墊不會正確MFC查看

第一個是顯示在通常的圖像軟件如MS畫圖和第二是我的MFC視圖。非常難的是,未經修改的圖像文件顯示得很好。我不確定這是SetDIBitsToDevice還是OpenCV的錯。但很明顯,SetDIBitsToDevice在每一行中丟失了不變的字節數。任何人有任何想法解決這個問題?

CorrectDisplayed

cv::Mat m_cvImage; 
static int Bpp(cv::Mat img) { return 8 * img.channels(); } 


void COpenCVTestView::OnDraw(CDC* pDC) 
{ 
COpenCVTestDoc* pDoc = GetDocument(); 
ASSERT_VALID(pDoc); 
if (!pDoc) 
    return; 
if(pDoc->m_cvImage.empty()) return; 
// TODO: add draw code for native data here 
int height=pDoc->m_cvImage.rows; 
int width=pDoc->m_cvImage.cols; 
uchar buffer[sizeof(BITMAPINFOHEADER) + 1024]; 
BITMAPINFO* bmi = (BITMAPINFO*)buffer; 
FillBitmapInfo(bmi,width,height,Bpp(pDoc->m_cvImage),0); 
SetDIBitsToDevice(pDC->GetSafeHdc(), 0, 0, width, 
    height, 0, 0, 0, height, pDoc->m_cvImage.data, bmi, 
    DIB_RGB_COLORS); 
} 


void COpenCVTestView::FillBitmapInfo(BITMAPINFO* bmi, int width, int height, int bpp, int origin) 
{ 
assert(bmi && width >= 0 && height >= 0 && (bpp == 8 || bpp == 24 || bpp == 32)); 

BITMAPINFOHEADER* bmih = &(bmi->bmiHeader); 

memset(bmih, 0, sizeof(*bmih)); 
bmih->biSize = sizeof(BITMAPINFOHEADER); 
bmih->biWidth = width; 
bmih->biHeight = origin ? abs(height) : -abs(height); 
bmih->biPlanes = 1; 
bmih->biBitCount = (unsigned short)bpp; 
bmih->biCompression = BI_RGB; 

if (bpp == 8) 
{ 
    RGBQUAD* palette = bmi->bmiColors; 

      for (int i = 0; i < 256; i++) 
    { 
     palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i; 
     palette[i].rgbReserved = 0; 
    } 
} 
} 

回答

3

作爲Roel says,位圖數據需要被DWORD對齊。然而,這是對問題的不完全描述; 每行的數據需要在DWORD邊界上開始。通常,在每行末尾插入0到3個字節的填充以確保這一點。

如果不方便或不可能墊行,只需確保圖像的寬度是4

+0

感謝您的解釋。 Roel對DWORD的說法完全一致,我完全被困惑了。現在我明白列數x通道數應該是4的倍數 – 2011-12-22 02:19:37

3

我沒有詳細研究你的榜樣,但要注意,你傳遞給的SetDIBitsToDevice數據需要在DWORD邊界(IIRC)對齊。也許你工作的90%的情況是相同的,並且事情意外地正確,並且當你旋轉對準開關時。

我希望,雖然在這種情況下,你不會看到任何輸出,但也許是GDI驅動程序檢測到錯誤的定位,不會做任何的blitting可言。聽起來很合理。

我想我張貼在DWORD邊界正確對齊與使用的SetDIBitsToDevice向SO早些時候,搜索我的帖子的代碼示例函數的一個例子。

+0

有一點可以肯定90%的病例整除是相同的大小不同。它可以從非常小的圖像到8MB圖像。其次,我沒有旋轉圖像。當我得到它時,它已經旋轉了。我還發現[相關答案你提到](http://stackoverflow.com/a/6759701/931170),但我沒有看到我的代碼有任何區別。然而,你的回答讓我更多地思考我的問題,我會盡快更新問題。不管怎麼說,還是要謝謝你。 – 2011-12-21 15:35:55

+0

我重讀這個問題,是的,它是一個有點不同的比我想象的 - 你正在使用的位圖數據直出你有OpenCV的數據(我該鏈路上的文章是關於傳遞到的SetDIBitsToDevice函數的數據是如何的malloc '編輯並填寫)。不過,您使用的數據需要按DWORD對齊,如果OpenCV能爲您做到這一點,我會感到驚訝。至於輪換,我不知道 - 我以爲你的意思是,你得到的數據是「預」旋轉,如此說來,這樣就在n行和n的cols交換,但也許還有別的東西的事OpenCV對象。 – Roel 2011-12-21 15:59:02

+0

我認爲你是對的。當我將圖像製作爲單通道灰度級時,圖像以奇怪的方式顯示 - 請查看我對圖片的回答。所以我想知道如何按照你的建議對DWORD進行對齊? – 2011-12-21 16:41:06