2011-12-14 6 views
5

मैंने सोचा कि एमएफसी व्यू पर ओपनसीवी 2 मैट प्रदर्शित करना सरल है लेकिन नहीं है। This is only relevant material I found on google। मुझे अपनी अज्ञानता के लिए क्षमा करें, लेकिन मुझे कोई अन्य सामग्री नहीं मिल रही है जो एक आयामी सरणी "डेटा" सदस्य रिटर्न के साथ SetDIBitsToDevice का उपयोग करने का तरीका दिखाती है। अधिक विशेष रूप से, मुझे यह जानने की जरूरत है कि फ़ंक्शन के लिए BITMAPINFO को कैसे निर्दिष्ट किया जाए। क्या मैं एमएफसी के साथ काम करने के लिए ओल्ड सी-स्टाइल ओपनसीवी पर वापस जाता हूं?एमएफसी व्यू पर ओपनसीवी मैट को प्रदर्शित करने के लिए कैसे करें

अद्यतन:

मैं an example of SetDIBitsToDevice जो पुराने सी-शैली OpenCV के लिए वास्तव में है पाया। लेकिन यह OpenCV2 के लिए इसे परिवर्तित करने के लिए सीधा था। कुछ चीजें मैं बनाने के लिए उल्लेख करने की जरूरत है यह काम कर रहे हैं:

  1. बीपीपी विधि चटाई की गहराई के रूप में अच्छी तरह से काम नहीं करता है देता है 0. मैं सिर्फ इस तरह बदल दिया है:

    static int Bpp(cv::Mat img) { return 8 * img.channels(); } 
    
  2. चटाई मूल नहीं है सदस्य। लेकिन FillBitmapInfo विधि के मूल तर्क के लिए बस 0 डालना ठीक है।

इसके अलावा, कोड बहुत अच्छा काम करता है। उम्मीद है कि यह अन्य देवताओं की भी मदद करता है।

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; 
    } 
} 
} 
+2

और क्या लिंक आपके द्वारा दी गई गलत है: निम्नलिखित कोड आप CImage को चटाई में बदल सकते हैं और उसके बाद CImage प्रदर्शित हर जगह आप चाहते हैं का उपयोग करना? – Sam

+0

@ vasile SetDIBitsToDevice पर दस्तावेज़ों के बावजूद, मैं एक आयामी सरणी "डेटा" सदस्य रिटर्न के साथ SetDIBitsToDevice का उपयोग करने का तरीका नहीं समझ सकता। –

+0

@ पॉल मैंने आपके उदाहरण को कई अन्य प्रश्नों/उत्तरों के आधार के रूप में देखा है। हालांकि, मैं सोच रहा हूं, 'FillBitmapInfo' फ़ंक्शन' में 'memset' के उपयोग से मेमोरी लीक से कैसे बचें? या किसी भी तरह से स्वचालित रूप से मुक्त हो जाता है? क्या आप इस संबंध में विस्तार कर सकते हैं। – adn

उत्तर

1

MSDN से:

[में] lpvBits बाइट्स की एक सरणी के रूप में जमा रंग डेटा के लिए एक सूचक। अधिक जानकारी के लिए, निम्नलिखित टिप्पणियां अनुभाग देखें।

यह पॉइंटर है जो आपको Mat :: डेटा से लौटाए गए डेटा के साथ init चाहिए।

+0

यहां आपको बस इतना ही चाहिए। http://msdn.microsoft.com/en-us/library/dd162974(v=vs.85).aspx बस इसे अपने लिए पढ़ें – Sam

+0

बीआईटीएमएपीआईएनएफओ एक संरचना है जिसमें फील्ड नाम स्पष्ट रूप से कह रहे हैं कि उनमें क्या शामिल है: BITMAPINFOHEADER-> चौड़ाई, ऊंचाई, आदि क्या आपने वास्तव में कभी उस पृष्ठ को पढ़ा था? कृपया मैट प्रलेखन भी पढ़ें। – Sam

+0

ठीक है, मैंने इसे कुछ समय पहले इस्तेमाल किया है, लेकिन ऊपर दिए गए संपादन को देखते हुए, यह याद रखने जितना आसान नहीं है। माफ़ कीजिये। – Sam

2

यहाँ MFC में OpenCV डेटा जो मैं का उपयोग प्रदर्शित करने का एक और संभव तरीका है और अच्छा काम करता है:

IplImage* image// <-- this contains the image you want to display 
CvvImage tempdefault; 
RECT myrect; // <-- specifiy where on the screen you want it to be displayed 
myrect.top = 0; 
myrect.bottom = _pictureh; 
myrect.left = _picturex; 
myrect.right = _picturew+_picturex; 
tempdefault.Create(_pictureh,_picturew,32); 
tempdefault.CopyOf(image); 
tempdefault.DrawToHDC(pDC->GetSafeHdc(),&myrect); 
+1

यह सुनिश्चित नहीं है कि मैं ओपनसीवी के समान संस्करण का उपयोग कर रहा हूं, लेकिन एक चटाई से आईपीएल इमेज में कनवर्ट करने के लिए, मैं बस करता हूं: 'सीवीएमएटी मैट = सीवीएमएटी (ऊंचाई, चौड़ाई, सीवी_8 यूसी 1, डेटा); IplImage * img = cvCreateImage (cvSize (ऊंचाई, चौड़ाई), आईपीएल_DEPTH_8U, 1); cvGetImage (और चटाई, आईएमजी); ' – Smash

+0

नहीं, मुझे नहीं पता कि यह तेज़ है या नहीं, यह बहुत आसान है;) – Smash

1

CvvImage OpenCV के नए संस्करण में उपलब्ध नहीं है।

int Mat2CImage(Mat *mat, CImage &img){ 
    if(!mat || mat->empty()) 
    return -1; 
    int nBPP = mat->channels()*8; 
    img.Create(mat->cols, mat->rows, nBPP); 
    if(nBPP == 8) 
    { 
    static RGBQUAD pRGB[256]; 
    for (int i = 0; i < 256; i++) 
     pRGB[i].rgbBlue = pRGB[i].rgbGreen = pRGB[i].rgbRed = i; 
    img.SetColorTable(0, 256, pRGB); 
    } 
    uchar* psrc = mat->data; 
    uchar* pdst = (uchar*) img.GetBits(); 
    int imgPitch = img.GetPitch(); 
    for(int y = 0; y < mat->rows; y++) 
    { 
    memcpy(pdst, psrc, mat->cols*mat->channels());//mat->step is incorrect for those images created by roi (sub-images!) 
    psrc += mat->step; 
    pdst += imgPitch; 
    } 

    return 0; 
} 
संबंधित मुद्दे