Модуль HighGUI, который предоставляет функции пользовательского интерфейса, кроме ползунка умеет так же обрабатывать события от мышки. Рассмотрим как OpenCV это делает.
Перейдём сразу к коду, который загружает картинку и при клике левой кнопкой мышки рисует на картинке целеуказатель.
Обработчик мышки привязывается с помощью функции cvSetMouseCallback(), причём привязка осуществляется к конкретному окну.
В данном случае события от мышки обрабатываются функцией myMouseCallback(), которая при клике левой кнопки мышки (CV_EVENT_LBUTTONDOWN) вызывает мою же функцию drawTarget(), которая рисует красный круг и перекрестие из двух линий.
#include <cv.h>
#include <highgui.h>
#include <stdlib.h>
#include <stdio.h>
IplImage* image = 0;
IplImage* src = 0;
// рисуем целеуказатель
void drawTarget(IplImage* img, int x, int y, int radius)
{
cvCircle(img,cvPoint(x, y),radius,CV_RGB(250,0,0),1,8);
cvLine(img, cvPoint(x-radius/2, y-radius/2), cvPoint(x+radius/2, y+radius/2),CV_RGB(250,0,0),1,8);
cvLine(img, cvPoint(x-radius/2, y+radius/2), cvPoint(x+radius/2, y-radius/2),CV_RGB(250,0,0),1,8);
}
// обработчик событий от мышки
void myMouseCallback( int event, int x, int y, int flags, void* param )
{
IplImage* img = (IplImage*) param;
switch( event ){
case CV_EVENT_MOUSEMOVE:
break;
case CV_EVENT_LBUTTONDOWN:
printf("%d x %d\n", x, y);
drawTarget(img, x, y, 10);
break;
case CV_EVENT_LBUTTONUP:
break;
}
}
int main(int argc, char* argv[])
{
// имя картинки задаётся первым параметром
char* filename = argc == 2 ? argv[1] : "Image0.jpg";
// получаем картинку
image = cvLoadImage(filename,1);
// клонируем картинку
src = cvCloneImage(image);
printf("[i] image: %s\n", filename);
assert( src != 0 );
// окно для отображения картинки
cvNamedWindow("original",CV_WINDOW_AUTOSIZE);
// вешаем обработчик мышки
cvSetMouseCallback( "original", myMouseCallback, (void*) image);
while(1){
// показываем картинку
cvCopyImage( image, src );
cvShowImage( "original", src );
char c = cvWaitKey(33);
if (c == 27) { // если нажата ESC - выходим
break;
}
}
// освобождаем ресурсы
cvReleaseImage(&image);
cvReleaseImage(&src);
// удаляем окно
cvDestroyWindow("original");
return 0;
}
Вот как у меня получилось накликать буквы CV (Computer Vision)
window_name — название окна, к которому привязывается событие
on_mouse — указатель на функцию-обработчик, которая будет вызываться для обработки события от мышки над заданным окном
param — дополнительный параметр, который можно передать функции-обработчику (в примере — это указатель на изображение)
функция-обработчик должна иметь вид:
typedef void (CV_CDECL *CvMouseCallback )(int event, int x, int y, int flags, void* param);
— копирует массив src в массив dst
mask — маска — 8-битный одноканальный массив, с помощью которой можно задать область для копирования
т.е. в dst будет скопированы только элементы src, для которых маска не равна нулю.
void cvLine(CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line type=8, int shift=0 );
— рисует отрезок линии между двумя точками
img — картинка для рисования
pt1 — начальная точка отрезка
pt2 — конечная точка отрезка
color — цвет линии, можно задать макросом CV_RGB(r, g, b)
thickness — толщина линии
type — тип линии (4-связанная,8-связанная или CV_AA — сглаживание)
shift — сдвиг
void cvCircle(CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int line type=8, int shift=0 );
— рисует круг
img — картинка для рисования
center — центр круга
radius — радиус круга
color — цвет линии, можно задать макросом CV_RGB(r, g, b)
thickness — толщина линии
type — тип линии (4-связанная,8-связанная или CV_AA — сглаживание)
shift — сдвиг
Связность, определяет число соседних пикселей. Т.е 4-связный- это только 4 пикселя: север, восток, юг и запад,
[ ][o][ ]
[o][x][o]
[ ][o][ ]
а у 8-связного ещё добавляются пиксели по-диагонали: северо-восточный, юго-восточный, юго-западный и северо-западный.
Прохожу эти уроки, только пишу на c#. В целом всё интуитивно понятно как переписать.
Не понятно в данном случае: зачем вообще использовать клонирование изображение? Удалил всё что касается переменной src — и так работает.
Комментарии (2)
RSS свернуть / развернутьНе понятно в данном случае: зачем вообще использовать клонирование изображение? Удалил всё что касается переменной src — и так работает.
JohnJ
noonv
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.