2013-09-02 2 views
0

어떻게 바이트 배열을 소켓에서받은 매트로 변환 할 수 있습니까? 이OpenCV C++ 바이트 배열을 매트로 변환

Mat frame; //colour image 
int imgSize = frame.total()*frame.elemSize(); 
int bytes = send(clientSock, frame.data, imgSize, 0));//write to the socket 

그리고 서버의 뜻처럼 컬러 이미지 데이터를 전송합니다

내 클라이언트 응용 프로그램은 내가 수신기에서 왜곡 된 이미지를 얻고

char sockData[imgSize]; 
    Mat img; 
    for (int i = 0; i < imgSize; i += bytes) { 
     bytes = recv(connectSock, sockData +i, imgSize - i, 0)); 
    } 

    // Write to mat 
    for (int i = 0; i < img.rows; i++) { 
     for (int j = 0; j < img.cols; j++) { 
     (img.row(i)).col(j) = (uchar)sockData[((img.cols)*i)+j]; 
     } 
    } 

같은 데이터를 수신합니다. 내 코드에 문제가 있습니까? 사전에 감사합니다 ....... 당신이 컬러 이미지가있는 경우

+0

왜 sockData는 char의 배열이며 uchar이 아닌가요? – Michele

+0

왜 cv :: Mat :: (x, y) 메서드를 사용하지 않습니까? x는 왼쪽에서 오른쪽으로의 열이고 y는 위에서 아래로의 열입니다 – Michele

+0

이미지가 컬러 인 경우 -> CV_8UC3 각 픽셀에 대해 8 비트의 3 채널이 있음 – Michele

답변

2

당신이 그렇게 코드의이 작품 변경 UCHAR의 3 개 채널 수학에서 그것을 읽을 수 있습니다 :이와

for (int i = 0; i < img.rows; i++) { 
    for (int j = 0; j < img.cols; j++) { 
    (img.row(i)).col(j) = (uchar)sockData[((img.cols)*i)+j]; 
    } 
} 

을 :

int baseIndex = 0; 
for (int i = 0; i < img.rows; i++) { 
    for (int j = 0; j < img.cols; j++) { 
    img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[baseIndex + 0], 
             sockData[baseIndex + 1], 
             sockData[baseIndex + 2]); 
    baseIndex = baseIndex + 3; 
    } 
} 

어쩌면 이것이 작동합니다.

+1

답장을 보내 주셔서 감사합니다 .... 귀하의 코드를 테스트했지만 여전히 왜곡 된 이미지와 나는 sockData 포인터가 (0,1,2), (1,2,3), (2,3,4) ....처럼 증가하고있는 이유를 발견했습니다. for for 루프 및 it (0,1,2), (3,4,5), (6,7,8), ...과 같은 것이어야합니다. 나는 방금 그 문제를 해결했다, 나는 그 아래에 게시 할 것이다 ... – Haris

+0

아, 그래, 미안하지만, 나는 색인이 어떻게 증가했는지 보지 않았다, 그냥 복사하여 붙여 넣기, 네가 맞아! – Michele

1

다음 코드를 사용하여 문제를 해결했습니다.

int ptr=0; 

for (int i = 0; i < img.rows; i++) { 
    for (int j = 0; j < img.cols; j++) { 

     img.at<cv::Vec3b>(i,j) = cv::Vec3b(sockData[ptr+0],sockData[ptr+1],sockData[ptr+2]); 
     ptr=ptr+3; 
    } 
    } 
0

작동하지 않습니까?

cv::Mat frame(img.rows, img.cols, CV_8UC3, sockData); 

그냥 올바른 이미지 형식으로 CV_8UC3 교체 :

CV_<bit-depth>{U|S|F}C(<number_of_channels>) 

은, 하나는이 문제를 해결하기 위해 MatIterator을 사용할 수 있습니다 미셸 응답에 추가 https://docs.opencv.org/2.4/modules/core/doc/basic_structures.html

1

참조하십시오.

cv::Mat m; 
m.create(10, 10, CV_32FC3); 

// This is the socket data. 
float *array = (float *)malloc(3*sizeof(float)*10*10); 

cv::MatIterator_<cv::Vec3f> it = m.begin<cv::Vec3f>(); 
for (unsigned i = 0; it != m.end<cv::Vec3f>(); it++) { 
    for (unsigned j = 0; j < 3; j++) { 
     (*it)[j] = *(array + i); 
     i++; 
    } 
} 

Now you have a float cv::Mat. In case of 8 bit, simply change float to uchar and Vec3f to Vec3b and CV_32FC3 to CV_8UC3 
관련 문제