2012-05-21 15 views
5

मैं एक सी ++ एप्लिकेशन बना रहा हूं जो ओपनसीवी और जेरोमक का उपयोग करता है। और एक zmq tcp सॉकेट पर cv :: Mat object (CV_8UC3) भेजने का प्रयास करते समय मुझे कुछ समस्याएं आ रही हैं। (सीवी में खराब पता :: मैट

#include <iostream> 
#include <zmq.hpp> 
#include <pthread.h> 
#include <opencv/cv.h> 
#include <opencv/highgui.h> 

using namespace std; 

int main() 
{ 
    zmq::context_t ctx(1); 
    zmq::socket_t mysocket(ctx, ZMQ_PUSH); 
    mysocket.bind("tcp://lo:4050"); 

    cv::VideoCapture capture(CV_CAP_ANY); 
    capture.set(CV_CAP_PROP_FRAME_WIDTH, 640); 
    capture.set(CV_CAP_PROP_FRAME_HEIGHT, 480); 

    cv::Mat3b frame; 

    capture >> frame; //First one is usually blank 
    capture >> frame; 
    capture >> frame; 

    cv::Mat3b clonedFrame(480, 640, CV_8UC3); 
    frame.copyTo(clonedFrame); 

    cout << "Original:" << endl 
     << "Address of data:\t" << &frame.data << endl 
     << "Size:\t\t\t" << frame.total() * frame.channels() << endl << endl; 

    cout << "Cloned:" << endl 
     << "Address of data:\t" << &clonedFrame.data << endl 
     << "Size:\t\t\t" << clonedFrame.total() * clonedFrame.channels() << endl << endl; 

    cout << "Gap between data:\t" << &clonedFrame.data - &frame.data << endl; 

    unsigned int frameSize = frame.total() * frame.channels(); 

    zmq::message_t frameMsg(frame.data, frameSize, NULL, NULL); 
    zmq::message_t clonedFrameMsg(clonedFrame.data, frameSize, NULL, NULL); 

    cv::imshow("original", frame); 
    cv::imshow("cloned", clonedFrame); 


    cvWaitKey(0); 

    if(frame.isContinuous()) 
    { 
     cout << "Sending original frame" << endl; 
     mysocket.send(frameMsg, 0); //This works 
     cout << "done..." << endl; 
    } 

    cvWaitKey(0); 

    if(clonedFrame.isContinuous()) 
    { 
     cout << "Sending cloned frame" << endl; 
     mysocket.send(clonedFrameMsg, 0); //This fails 
     cout << "done..." << endl; 
    } 

    return EXIT_SUCCESS; 
} 

बाद भेजने) zmq कुछ दावे असफल बनाता है:

यहाँ अद्यतन कोड नमूना है। उत्पादन:

Original: 
Address of data: 0xbfdca480 
Size:   921600 

Cloned: 
Address of data: 0xbfdca4b8 
Size:   921600 

Gap between data: 14 
Sending original frame 
done... 
Sending cloned frame 
Bad address 
done... 
nbytes != -1 (tcp_socket.cpp:203) 

क्यों क्लोन() गंदगी सूचक, और कैसे मैं इस का समाधान कर सकते है?

किसी भी मदद की सराहना की जाती है।

2012-05-25 संपादित करें: कोड नमूना अपडेट किया गया। मैं संदेश कन्स्ट्रक्टर को निम्न पॉइंटर्स में से एक देकर मूल फ्रेम भेज सकता हूं: frame.ptr(), frame.data, frame.datastart, frame.at()। वे सभी मूल के लिए काम करते हैं, लेकिन कन्स्ट्रक्टर के लिए कोई भी नहीं। जैसा कि आप देख सकते हैं, दो डेटापॉइंटर्स के बीच पता स्थान छोटा है। कम से कम फ्रेम आकार नहीं होना चाहिए?

// जॉन

+0

मुझे यकीन है कि नहीं हूँ, लेकिन मुझे लगता है कि जब आप सीवी :: चटाई clonedFrame = frame.clone() करते हैं, आप फ्रेम के लिए एक सूचक बना रहे हैं। आप फ्रेम.copyTo (क्लोनफ्रेम) करने की कोशिश क्यों नहीं करते हैं; । इस तरह छवि को निश्चित रूप से कॉपी किया गया है। कोशिश करो, बस मामले में। –

+0

मैंने भी कोशिश की। लेकिन यह एक ही परिणाम देता है। सीवी :: मैट संदर्भ कहता है कि क्लोन() मैट्रिक्स की एक पूर्ण प्रति बनाता है और यह प्रतिलिपि() गंतव्य पर सभी डेटा कॉपी करता है। अंतर को पूरी तरह से समझें नहीं ... – John

+0

हाँ, आप सही हैं। यह अजीब है। प्रत्येक चरण पर प्रत्येक मट गुणों को डीबग और जांचने का प्रयास करें: डेटा, डेटास्टार्ट, आकार, चरण। हो सकता है कि आपको 2 मैट्रिस के बीच अंतर और यह असफल क्यों हो रहा है, के बारे में एक सुराग प्राप्त हो। –

उत्तर

0

ठीक है ... तो मैं अपने खुद के प्रति समारोह

यह इस तरह दिखता है बनाने समाप्त हो गया:

struct frameData_t 
{ 
    unsigned char *data; 
    size_t size; 
}; 

struct frameData_t *copyMatData(cv::Mat3b &indata) 
{ 
    struct frameData_t *ret = new struct frameData_t; 

    ret->size = indata.total() * indata.channels(); 
    ret->data = new unsigned char[ret->size]; 

    int datapos = 0; 
    for(int channel = 0; channel < indata.channels(); channel++) 
    { 
     for(int row = 0; row < indata.rows; row++) 
     { 
      const cv::Vec3b *srcrow = indata[row]; 
      for(int col = 0; col < indata.cols; col++, datapos++) 
      { 
       ret->data[datapos] = srcrow[col][channel]; 
      } 
     } 
    } 

    return ret; 
} 

और मैं इसे इस तरह का उपयोग करें:

struct frameData_t *clonedFrame = copyMatData(frame); 
zmq::message_t frameMsg(frame.data, frameSize, NULL, NULL); 
mysocket.send(clonedFrameMsg, 0); 

यदि कोई बेहतर तरीके से जानता है, तो कृपया मुझे बताएं।

// जॉन

संबंधित मुद्दे