Я написал демо для отображения изображения и рисования маленьких зеленых точек, пока ваша мышь двигается , см. Ниже.
Вы должны знать, что OpenCV не был разработан для этого типа взаимодействия , поэтому производительность является проблемой (и это плохо)! Вы поймете, что я имею в виду.
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
// mouse callback
void on_mouse(int event, int x, int y, int flags, void* param)
{
// Remove comment below to paint only when left mouse button is pressed
//if (event == CV_EVENT_LBUTTONDOWN)
{
//fprintf(stderr, "Painting at %dx%d\n", x, y);
IplImage* img = (IplImage*)param;
cvCircle(img, cvPoint(x,y), 1, CV_RGB(0, 255, 0), -1, CV_AA, 0);
cvShowImage("cvPaint", img);
}
}
int main(int argc, char* argv[])
{
if (argc < 2)
{
fprintf( stderr, "Usage: %s <img>\n", argv[0]);
return -1;
}
IplImage* frame = NULL;
frame = cvLoadImage(argv[1], CV_LOAD_IMAGE_UNCHANGED);
if (!frame)
{
fprintf( stderr, "Failed: Couldn't load file %s\n", argv[1]);
return -1;
}
cvNamedWindow("cvPaint", CV_WINDOW_AUTOSIZE);
cvShowImage("cvPaint", frame);
cvSetMouseCallback("cvPaint", &on_mouse, frame);
while (1)
{
// Keep looping to prevent the app from exiting,
// so the mouse callback can be called by OpenCV and do some painting
char key = cvWaitKey(10);
if (key == 113 || key == 27) // q was pressed on the keyboard
break;
}
cvReleaseImage(&frame);
cvDestroyWindow("cvPaint");
return 0;
}
Я предлагаю, чтобы вы использовали какую-либо другую оконную систему для этого типа задачи , где производительность выше. Взгляните, например, на Qt . Но вы также можете использовать собственные платформы, такие как win32 или X , если хотите.
Что касается другой части вопроса, как обрезать по выбору пользователя, я предлагаю вам взглянуть на код, доступный по адресу: Изменение размера OpenCV и обрезка изображения в соответствии со значением пикселя
Кроме того, записывать координаты мыши, пока пользователь рисует изображение, гораздо удобнее, чем анализировать изображение на предмет нарисованных зеленых точек. Затем проанализируйте эти координаты и извлеките из них наименьшую площадь прямоугольника. Вот когда эта логика становится полезной:
CvScalar s;
for (x=0; x<width-1; x++)
{
for(y=0; y<height-1; y++)
{
s = cvGet2D(binImage, y, x);
if (s.val[0] == 1)
{
minX = min(minX, x);
minY = min(minY, y);
maxX = max(maxX, x);
maxY = max(maxY, y);
}
}
}
cvSetImageROI(binImage, cvRect(minX, minY, maxX-minX, maxY-minY));
В этом конкретном случае вместо итерации по изображению в поисках конкретных пикселей, как это сделал пользователь в этом вопросе, вы будете перебирать массив координат, записанных во время движения мыши.