2012-05-21 16 views
5

Opencv ve zeromq kullanan bir C++ uygulaması yapıyorum. Ve bir zmq tcp soketi üzerinden bir cv :: Mat nesnesini (CV_8UC3) göndermeye çalışırken bazı sorunlar yaşıyorum.) (cv :: Mat dosyasında hata yok

#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; 
} 

ikincisi gönderme zmq bazı iddiasını başarısız yapar: Burada

güncellenmiş kod örneğidir. çıkışı:

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) 

Neden klon() pisliği işaretçi ve bunu nasıl çözebilir ki?

Herhangi bir yardım için teşekkür ederiz.

Edit 2012-05-25: Kod örneği güncellendi. İleti kurucusuna şu işaretçilerden birini vererek orijinal çerçeveyi gönderebilirim: frame.ptr(), frame.data, frame.datastart, frame.at(). Hepsi orijinal için çalışıyorlar, ancak yapıcı için yok. Gördüğünüz gibi, iki veri yazıcısı arasındaki adres alanı küçüktür. En azından frameSize olmaz mı?

// John

+0

Emin değilim, ama sanırım bu size cv :: Mat clonedFrame = frame.clone() ne zaman; çerçeveye bir işaretçi oluşturuyorsunuz. Neden frame.copyTo (clonedFrame) yapmayı denemiyorsunuz; . Bu şekilde görüntü kesin olarak kopyalanır. Hemen dene. –

+0

Bunu da denedim. Ama aynı sonucu veriyor. cv :: Mat referansı, klonun() matrisin tam bir kopyasını oluşturduğunu ve copyto() öğesinin tüm verileri hedefe kopyalardığını belirtir. Farkı tam olarak anlama ... – John

+0

Evet, haklısın. Bu garip. Her adımda her Mat özelliğini hata ayıklamaya ve kontrol etmeye çalışın: veri, veri başlatma, boyut, adım. Belki de 2 matris arasındaki fark ve neden başarısız olduğu hakkında bir ipucu elde edersiniz. –

cevap

0

Tamam ... Bu yüzden kendi kopyalama işlemini

Bu şuna benzer hale sona erdi: Ve bu gibi kullanmak

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); 

Daha iyi bir yoldan haberi varsa, lütfen bize bildirin.

// John