我不會進入所有的細節,爲什麼你的做法是不好的,但請記住,對於繪圖創建2個額外的幀是有點太多了。
重要的是,您意識到所有這些淫事正在用於捕獲新幀的相同線程上完成。這意味着什麼?這意味着您在循環內添加的額外代碼將減慢捕獲和顯示新幀的過程。換句話說,你正在通過降低應用程序的幀率來破壞自己。如果你不在乎,沒關係。如果你這樣做,我的提示是你將捕獲的幀堆疊到一個緩衝區中,並讓另一個線程讀取,處理並顯示它們。
好的,所以你REALLY想繪製顯示捕獲幀的窗口。那麼,明顯的事情你不能做(你自己也發現了這個)是因爲在每個循環中它被替換爲新數據的幀不能在捕獲的幀上進行繪製。所以你會怎麼做?您創建第二個框架來完成繪圖。我們稱之爲drawing_frame。
drawing_frame唯一會出現的情況是,當鼠標移動到窗口上時,鼠標的LBUTTON被點擊(第二次點擊在ON/OFF之間切換)時將出現這些圓圈。
圓的繪製發生後,的drawing_frame被覆蓋在頂部由照相機捕獲的框架上。這個過程在CPU上有點貴,而且由於我們在應用程序的主線程中這樣做,它也會降低幀率。
我強烈建議大家感興趣的添加/合併/覆蓋與OpenCV的透明幀看一看Transparent image overlays in OpenCV。我使用的是cvCaptureFromCAM(-1)
,因爲我在Linux上。你可能應該改變爲適合你的任何東西。根據你的帖子,它的cvCaptureFromCAM(0)
。
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
int drawing = 0;
int last_x = 0;
int last_y = 0;
void on_mouse(int event, int x, int y, int flags, void* param)
{
last_x = x;
last_y = y;
if (event == CV_EVENT_LBUTTONDOWN)
{
// switches between On and Off
if (drawing)
drawing = 0;
else
drawing = 1;
}
}
int main()
{
CvCapture* capture = NULL;
if ((capture = cvCaptureFromCAM(-1)) == NULL)
{
fprintf(stderr, "ERROR: capture is NULL \n");
return -1;
}
cvNamedWindow("mywindow", CV_WINDOW_AUTOSIZE);
cvQueryFrame(capture); // Sometimes needed to get correct data
cvSetMouseCallback("mywindow",&on_mouse, 0);
IplImage* frame = NULL;
IplImage* drawing_frame = NULL;
while (1)
{
if ((frame = cvQueryFrame(capture)) == NULL)
{
fprintf(stderr, "ERROR: cvQueryFrame failed\n");
break;
}
if (frame == NULL)
{
fprintf(stderr, "WARNING: cvQueryFrame returned NULL, sleeping..\n");
usleep(100000);
continue;
}
if (!drawing_frame) // This frame is created only once
{
drawing_frame = cvCreateImage(cvSize(frame->width, frame->height), frame->depth, frame->nChannels);
cvZero(drawing_frame);
}
if (drawing)
{
cvCircle(drawing_frame, cvPoint(last_x,last_y), 10,CV_RGB(0, 255, 0), -1, CV_AA, 0);
// For overlaying (copying transparent images) in OpenCV
// http://www.aishack.in/2010/07/transparent-image-overlays-in-opencv/
for (int x = 0; x < frame->width; x++)
{
for (int y = 0; y < frame->height; y++)
{
CvScalar source = cvGet2D(frame, y, x);
CvScalar over = cvGet2D(drawing_frame, y, x);
CvScalar merged;
CvScalar S = { 1,1,1,1 };
CvScalar D = { 1,1,1,1 };
for(int i = 0; i < 4; i++)
merged.val[i] = (S.val[i] * source.val[i] + D.val[i] * over.val[i]);
cvSet2D(frame, y, x, merged);
}
}
}
cvShowImage("mywindow", frame);
int key = cvWaitKey(10);
if (key == 113) // q was pressed on the keyboard
break;
}
cvReleaseImage(&frame);
cvReleaseImage(&drawing_frame);
cvReleaseCapture(&capture);
cvDestroyWindow("mywindow");
return 0;
}
與我的興趣有關。你能在這裏發表評論嗎?你在使用什麼文檔/教程?我想在OpenCV中獲得自己的開始。謝謝 – sdadffdfd 2011-03-30 19:23:28
對於我們來說,重新審視問題並接受解決問題的答案非常重要。 – karlphillip 2011-03-31 14:30:46