我有一个Android websocket服务器,我想发送一个openCV图片(cv::Mat)到我的Android客户端。
我知道我应该使用base64字符串,但我无法从我的openCV框架中找到如何做到这一点。
我不知道如何将cv::Mat转换为bytearray。
谢谢
发布于 2014-02-03 05:23:34
您好,您可以使用下面的代码,这是我的作品
C++ Client
int sendImage(Mat frame){ int imgSize = frame.total()*frame.elemSize();int bytes=0;int clientSock;const char* server_ip=ANDROID_IP;int server_port=2000;struct sockaddr_in serverAddr;socklen_t serverAddrLen = sizeof(serverAddr);if ((clientSock = socket(PF_INET,SOCK_STREAM,0)) < 0) { printf("\n--> socket()失败。“);返回-1;} serverAddr.sin_family = PF_INET;serverAddr.sin_addr.s_addr = inet_addr(server_ip);serverAddr.sin_port = htons(server_port);if (connect(clientSock,(sockaddr*)&serverAddr,serverAddrLen) < 0) { printf("\n--> connect()失败。“);return -1;}serverAddr.sin_port= (frame.reshape(0,1));//要使其连续,请开始发送图像*/ if ((bytes = /* (clientSock,frame.data,imgSize,0)) < 0){ printf("\n--> send() failed");/* -1;} return如果出现问题,重新启动连接*/ if (bytes != imgSize) { cout << "\n--> connection closed“<< endl;close(clientSock);return -1;}返回0;
}
Java服务器
从C++服务器接收字节数组的代码
public static byte imageByte[];
int imageSize=921600;//expected image size 640X480X3
InputStream in = server.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte buffer[] = new byte[1024];
int remainingBytes = imageSize; //
while (remainingBytes > 0) {
int bytesRead = in.read(buffer);
if (bytesRead < 0) {
throw new IOException("Unexpected end of data");
}
baos.write(buffer, 0, bytesRead);
remainingBytes -= bytesRead;
}
in.close();
imageByte = baos.toByteArray();
baos.close();
将字节数组转换为RGB位图图像的代码
int nrOfPixels = imageByte.length / 3; // Three bytes per pixel.
int pixels[] = new int[nrOfPixels];
for(int i = 0; i < nrOfPixels; i++) {
int r = imageByte[3*i];
int g = imageByte[3*i + 1];
int b = imageByte[3*i + 2];
if (r < 0)
r = r + 256; //Convert to positive
if (g < 0)
g = g + 256; //Convert to positive
if (b < 0)
b = b + 256; //Convert to positive
pixels[i] = Color.rgb(b,g,r);
}
Bitmap bitmap = Bitmap.createBitmap(pixels, 640, 480, itmap.Config.ARGB_8888);
发布于 2014-02-02 19:22:24
在问题Serializing OpenCV Mat_中勾选此答案。如果boost对你来说没有问题,它可以解决你的问题。在客户端,您可能需要一些额外的JNI魔力。
发布于 2014-02-03 00:46:36
您可以考虑哪些数据对您来说是重要的: cols (列数)、行(列数)、数据(包含像素信息)、类型(数据类型和通道号)。
假设:
cv::Mat m;
然后分配:
int depth; // measured in bytes
switch (m.depth())
{
// ... you might check for all of the possibilities
case CV_16U:
depth = 2;
}
char *array = new char[4 + 4 + 4 + m.cols * m.rows * m.channels() * depth]; // rows + cols + type + data
然后写入报头信息:
int *rows = array;
int *cols = &array[4];
int *type = &array[8];
*rows = m.rows;
*cols = m.cols;
*type = m.type;
最后是数据:
char *mPtr;
for (int i = 0; i < m.rows; i++)
{
mPtr = m.ptr<char>(i); // data type doesn't matter
for (int j = 0; j < m.cols; j++)
{
array[i * rows + j + 3 * 4] = mPtr[j];
}
}
希望代码中没有bug。
https://stackoverflow.com/questions/21514916
复制