Sending Opencv images from Android to PC over TCP

asked 2014-01-15 05:25:00 -0500

Roy08 gravatar image

I'm working on a Android app that grabs a image and sends it to a PC client for display, both the Android app and PC application use Opencv. The image that i want to send over is a color image (grabbed in the rbga format).

First i grab a image in the java app using:

InputImage = inputFrame.rgba();

Next i am using the Mat image variabele and convert the input image to a byte array using the following native (using JNI) function:

    JNIEXPORT jbyteArray JNICALL Java_com_example_communicationmoduleTCPIP_communicationmoduleTCPIP_ConvertImageToByteArray(
        JNIEnv* Env, jobject,
        jlong addrInputImage){

    Mat& OutputImg = *(Mat*) addrInputImage;
    jbyteArray Array;

    //__android_log_write(ANDROID_LOG_ERROR, "Tag", "==== 1 ");

    // Init  java byte array
    Array = Env->NewByteArray(1536000);

    //__android_log_write(ANDROID_LOG_ERROR, "Tag", "==== 2 ");

    // Set byte array region with the size of the SendData CommStruct.
    // Now we can send the data back.
    Env->SetByteArrayRegion(Array, 0, 1536000, (jbyte*)OutputImg.data);

    //__android_log_write(ANDROID_LOG_ERROR, "Tag", "==== 3 ");

        return Array;
}

Next is end the byte array (containing the image data) over TCP with the following function:

    // Send buffer, the method can be used by both client and server objects.
    public void SendByteBuffer(byte[] ByteBuffer){

    try {                         
        // Get socket output stream
        OutputStream OutputBuffer = ClientSocket.getOutputStream();

        //Write byte data to outputstream
        OutputBuffer.write(ByteBuffer);  

    } 
    catch (IOException e) {
        Log.e("TCPIPCommunicator: ", "Client: Failed to send", e);
        e.printStackTrace();
    }  
}

On the PC side (in c++) i recieve the buffer with a boost lib recieve function:

int CommunicationModuleTCPIPServer::RecieveBuffer(char Buffer[], int Size){

boost::asio::read(ServerSocket, boost::asio::buffer(TempBuffer, 1536000));
//boost::asio::read(ServerSocket, boost::asio::buffer((char*)InputImage, Size));
//cout <<"Temp buffer: " << TempBuffer << endl;


 int ptr=0;
 for (int i = 0;  i < InputImage.rows; i++) {
  for (int j = 0; j < InputImage.cols; j++) {
      InputImage.at<cv::Vec4b>(i,j) = cv::Vec4b(TempBuffer[ptr+ 0],TempBuffer[ptr+1],TempBuffer[ptr+2],TempBuffer[ptr+3]);
   ptr=ptr+4;
   }
  }

return COMMSUCCES;

}

And then i display the variable with the imshow function of opencv. The problem is that i don't get a image in the window on the pc side. i'm thinking the conversion is going wrong somewhere but i dont' see where. Does anybody have a idea? All suggestions and feedback are welcome!

edit retag flag offensive close merge delete

Comments

try to print out some pixels:

cout << InputImage(Rect(0,0,10,10)) << endl;


it won't change your problem, but i think, you can skip the for() loop in the client. just make a Mat tmp(h,w,CV_8U_C4, TempBuffer); and myMat = tmp.clone(); // for a deep copy

berak gravatar imageberak ( 2014-01-15 07:41:07 -0500 )edit

Thank you for yout comments, does anybody know a good example or solution?

Roy08 gravatar imageRoy08 ( 2014-01-15 08:21:02 -0500 )edit

I thin te problem is the conversion between the rbga image->mat->byte array en back. Can anyone see a problem?

Roy08 gravatar imageRoy08 ( 2014-01-15 08:26:17 -0500 )edit

boost::asio::read returns the number of bytes read.

you should check that.

berak gravatar imageberak ( 2014-01-16 11:06:22 -0500 )edit

can you show me your initialization of client socket

vajira gravatar imagevajira ( 2017-09-07 01:35:52 -0500 )edit