我想在兩個linux進程之間共享一個CvMat對象(OpenCV庫中的一個矩陣),爲此我使用共享內存。一個進程(服務器)將從網絡攝像頭捕獲一幀(矩陣),將其轉換爲灰度,使用共享內存共享並在屏幕上顯示幀。另一個進程(客戶端)將讀取共享幀並執行一些操作。請參閱下面的代碼。opencv矩陣到共享內存
問題似乎是由於'rows'和'cols'爲零(或者服務器沒有寫入共享內存),客戶端沒有讀取信息。無論如何,我沒有收到任何錯誤信息,我不知道我做錯了什麼。任何想法?
非常感謝!
這裏是服務器的代碼:
#include <iostream>
#include <cv.h>
#include <highgui.h>
using namespace std;
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include "2cam.h"
int sizeofmat(CvMat *mat) {
return mat->rows * mat->cols * CV_ELEM_SIZE(mat->type);
}
int main() {
int shmid;
key_t key = 5678;
CvMat *vdisp = cvCreateMat(240, 320, CV_8U);
const size_t vdispsize = sizeofmat(vdisp);
CvMat *s = cvCreateMat(240, 320, CV_8U);
CvMat stub;
CvSize imageSize = cvSize(320, 240);
IplImage *color = cvCreateImage(imageSize, 8, 3);
IplImage *gray = cvCreateImage(imageSize, 8, 1);
/* Create the segment */
if ((shmid = shmget(key, vdispsize, IPC_CREAT | 0666)) < 0) {
perror("shmget");
exit(1);
}
/* Attach the segment to our data space */
if ((vdisp = (CvMat *)shmat(shmid, NULL, 0)) == (CvMat *)-1) {
perror("shmat");
exit(1);
}
/* Put CvMat into the memory to be read for other processes */
s = vdisp;
/* Create camera */
Camera c("/dev/video0", 320, 240, 30);
while (1) {
/* Get one frame */
c.Update();
c.toIplImage(color);
/* Convert color frame to grayscale */
cvCvtColor(color, gray, CV_BGR2GRAY);
/* Get matrix from the gray frame and write the matrix in shared memory*/
s = cvGetMat(gray, &stub, 0, 0);
/* Show frame */
cvNamedWindow("result", CV_WINDOW_AUTOSIZE);
cvShowImage("result", s);
/* Wait for escape key */
if ((cvWaitKey(10) & 255) == 27)
break;
}
/* free memory */
cvDestroyWindow("result");
cvReleaseImage(&color);
cvReleaseImage(&gray);
//cvReleaseMat(&vdisp);
//cvReleaseMat(&s);
return 0;
}
在這裏,客戶端的代碼:
#include <iostream>
#include <cv.h>
#include <highgui.h>
using namespace std;
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
int sizeofmat(CvMat *mat) {
return mat->rows * mat->cols * CV_ELEM_SIZE(mat->type);
}
int main() {
int shmid;
key_t key = 5678;
CvMat *vdisp = cvCreateMat(240, 320, CV_8U);
const size_t vdispsize = sizeofmat(vdisp);
CvMat *s = cvCreateMat(240, 320, CV_8U);
/* Locate the segment */
if ((shmid = shmget(key, vdispsize, 0666)) < 0) {
perror("shmget");
exit(1);
}
/* Now we attach the segment to our data space */
if ((vdisp = (CvMat *)shmat(shmid, NULL, 0)) == (CvMat *) -1) {
perror("shmat");
exit(1);
}
s = vdisp;
cout << "rows: " << s->rows << endl;
cout << "cols: " << s->cols << endl;
return 0;
}
難道你不能使用線程嗎? – karlphillip 2010-10-11 13:15:20
yeap!沒問題,但它是一個個人項目,所以我決定使用共享內存來了解它是如何工作的。感謝您的建議。 – 2010-10-11 13:18:26
如果你想要它的功能和速度,只需使用gstreamer的'shmsrc'和'shmsink'(OpenCV示例:https://github.com/tik0/mat2gstreamer) – Tik0 2016-09-03 12:38:12