brutalis 5 Жалоба Опубликовано February 14, 2014 доброго времени суток. возник такой вопрос. есть ип-камера, я получаю с нее картинку. мне нужно, скажем, каждый 5 кадр с нее сверять с известной картиной(png или jpg). и если есть совпадение сообщить об этом как нибудь.(сигнал или функция) подскажите пожалуйста как это реализовать. и где можно посмотреть описание с примерами. зы. как вывести изображение на форму а не в отдельном окне pps использую opencv и qt5 образцы картинок и исходники в архивеcamera.rar Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
dereyly 6 Жалоба Опубликовано February 14, 2014 Здравствуйте Сопсотавление картинок можно сделать на основе особых точек SURF или ORB. http://docs.opencv.org/doc/tutorials/features2d/feature_description/feature_description.html?highlight=match%20surf 1. Найдите особые точки на интересующей картинке и вычислите их дескрипторы 2. Каждый N-ый кадр ищите особые точки и их дескрипторы 3. Сопоставть особые точке 4. Если после RANSAC количество точек в процентном соотношениие велико, то можно считать это совпадением ЕСть еще такой проект на qt https://code.google.com/p/find-object/ 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
mrgloom 242 Жалоба Опубликовано February 14, 2014 проблема только в том, что как уже ранее говорилось, такой подход ищет только тот же самый объект, а не класс объекта, хотя в изначальном условии не уточнено. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано February 16, 2014 Здравствуйте Сопсотавление картинок можно сделать на основе особых точек SURF или ORB. http://docs.opencv.org/doc/tutorials/features2d/feature_description/feature_description.html?highlight=match%20surf 1. Найдите особые точки на интересующей картинке и вычислите их дескрипторы 2. Каждый N-ый кадр ищите особые точки и их дескрипторы 3. Сопоставть особые точке 4. Если после RANSAC количество точек в процентном соотношениие велико, то можно считать это совпадением ЕСть еще такой проект на qt https://code.google.com/p/find-object/ спс. буду пробовать Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано February 26, 2014 Всем доброго времени суток. по поводу моего предыдудщего поста о выводе iplimage в qlabel подошло следующее решение #include <cv.h> #include <highgui.h> using namespace std; using namespace cv; IplImage* imgTracking=0; QImage MainWindow::IplImage2QImage(const IplImage *iplImage) { int height = iplImage->height; int width = iplImage->width; const uchar *qImageBuffer =(const uchar*)iplImage->imageData; QImage img(qImageBuffer, width, height, QImage::Format_RGB888); return img.rgbSwapped(); } void MainWindow::on_pushButton_clicked() { CvCapture *cap; cap = cvCaptureFromCAM(1); IplImage *frame; frame = cvQueryFrame(cap); bool play = true; while(frame && play){ cvWaitKey(10); IplImage *img = cvCloneImage(frame); if (img->origin) { cvFlip(img); img->origin= 0; } QImage qimg; qimg = IplImage2QImage(img); //cvShowImage("Video", frame); ui->labVideo->setPixmap(QPixmap::fromImage(qimg)); cvReleaseImage(&img); frame = cvQueryFrame(cap); } cvReleaseCapture(&cap); } теперь у меня другая проблема. мне нужно вывести 2 картинки. оригинал и обработанную(детектор границ кенни). оригинал на qlabel выводится отлично. а при выводе обработанного изображения на qlabel прога критует/ до этого когда в 2 окна через cvShowImage выодил все работало ок. подскажите в чем может быть проблема. вот код #include "highgui.h" #include "cv.h" #include "ml.h" #include "stdlib.h" #include "stdio.h" #include <ctype.h> using namespace cv; IplImage* frame = 0; IplImage* dst = 0; IplImage* dst2 = 0; IplImage* imgTracking=0; //преобразуем iplimage в qimage QImage IplImage2QImage(const IplImage *iplImage) { int height = iplImage->height; int width = iplImage->width; const uchar *qImageBuffer =(const uchar*)iplImage->imageData; QImage img(qImageBuffer, width, height, QImage::Format_RGB888); return img.rgbSwapped(); } //детектор границ кенни void MainWindow::on_kennydetekt_clicked() { CvCapture* capture = cvCaptureFromCAM( 1 ); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if(capture == NULL)// Если камер не обнаружено proverka();assert( capture ); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);//1280); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT,240);//960); int counter=0; char filename[512]; while(true){ // получаем кадр frame = cvQueryFrame( capture ); // показываем // создаём одноканальные картинки // gray = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 ); dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 ); // преобразуем в градации серого //cvCvtColor(frame, gray, CV_RGB2GRAY); // получаем границы cvCanny(frame, dst, 20, 60, 3); // тянем frame на qlabel IplImage *img = cvCloneImage(frame); QImage qimg; qimg = IplImage2QImage(img); // cvShowImage("Video", frame); ui->lbloriginal->setPixmap(QPixmap::fromImage(qimg)); cvReleaseImage(&img); frame = cvQueryFrame(capture); //обработанное видео cvShowImage("postcapture", dst); /* IplImage *img1 = cvCloneImage(dst); QImage qimg1; qimg1 = IplImage2QImage(dst); ui->lblprocessed->setPixmap(QPixmap::fromImage(qimg1)); cvReleaseImage(&img1); dst = cvQueryFrame(capture); */ char c = cvWaitKey(33); if (c == 27) {break;} // нажата ESC else if(c == 13) { // Enter сохраняем кадр в файл sprintf(filename, "Image%d.jpg", counter); printf("[i] capture... %s\n", filename); cvSaveImage(filename, frame);cvSaveImage(filename, dst); counter++;}} // освобождаем ресурсы cvReleaseCapture( &capture ); cvDestroyWindow("capture");cvDestroyAllWindows(); } проблемная часть закоментированна Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 26, 2014 Может быть в том, что ты gray используешь? Конвертируй перед выводом в rgb. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано February 27, 2014 Дык у меня вроде за клиент трова она строка гдч я в grey реревожу или я не прав? Извинчюсь за ошибки и знаки поипинагия Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано February 27, 2014 Какое ты изображение создаёшь? Серое:dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 ); А выводишь какое? Цветное rgb:QImage img(qImageBuffer, width, height, QImage::Format_RGB888); Что-то мне подсказывает, что тут несостыковочка есть 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано March 3, 2014 Какое ты изображение создаёшь? Серое:dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 ); А выводишь какое? Цветное rgb:QImage img(qImageBuffer, width, height, QImage::Format_RGB888); Что-то мне подсказывает, что тут несостыковочка есть Спасибо за разъяснение. самостоятельно решить проблему вывода обработанного избражения не получается. подскажите что и где нужно исправить чтобы заработало. спасибо. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 3, 2014 Внутри функции IplImage2QImage проверяй iplImage->nChannels == 3 Если число каналов равно 1, то создавай трёхканальное изображение и делай в него cvCvtColor с параметром CV_GRAY2RGB. Потом это новое изображение и подавай сюда: const uchar *qImageBuffer =(const uchar*)iplImage->imageData; Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано March 3, 2014 Внутри функции IplImage2QImage проверяй iplImage->nChannels == 3 Если число каналов равно 1, то создавай трёхканальное изображение и делай в него cvCvtColor с параметром CV_GRAY2RGB. Потом это новое изображение и подавай сюда: const uchar *qImageBuffer =(const uchar*)iplImage->imageData; а можете расписать(примерчик или код), а то что то я совсем не соображаю спасибо Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 4, 2014 Пишу навскидку: //преобразуем iplimage в qimage QImage IplImage2QImage(const IplImage* iplImage) { int height = iplImage->height; int width = iplImage->width; IplImage* tmpImage = NULL; if (iplImage->nChannels == 1) { tmpImage = cvCreateImage(cvGetSize(iplImage), iplImage->depth, 3); cvCvtColor(iplImage, tmpImage, CV_GRAY2BGR); } const uchar* qImageBuffer = tmpImage ? (const uchar*)tmpImage->imageData : (const uchar*)iplImage->imageData; QImage img(qImageBuffer, width, height, QImage::Format_RGB888); if (tmpImage) { cvReleaseImage(&tmpImage); } return img.rgbSwapped(); } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано March 4, 2014 ОГромное спасибо Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано March 4, 2014 Пишу навскидку: //преобразуем iplimage в qimage QImage IplImage2QImage(const IplImage* iplImage) { int height = iplImage->height; int width = iplImage->width; IplImage* tmpImage = NULL; if (iplImage->nChannels == 1) { tmpImage = cvCreateImage(cvGetSize(iplImage), iplImage->depth, 3); cvCvtColor(iplImage, tmpImage, CV_GRAY2BGR); } const uchar* qImageBuffer = tmpImage ? (const uchar*)tmpImage->imageData : (const uchar*)iplImage->imageData; QImage img(qImageBuffer, width, height, QImage::Format_RGB888); if (tmpImage) { cvReleaseImage(&tmpImage); } return img.rgbSwapped(); } Спасибо. помогло. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано March 4, 2014 тепрь у меня возникла следующая проблема. если я тут//обработанное видео cvShowImage("postcapture", dst); IplImage *img1 = cvCloneImage(dst); QImage qimg1; qimg1 = IplImage2QImage(dst); ui->lblprocessed->setPixmap(QPixmap::fromImage(qimg1)); cvReleaseImage(&img1); dst = cvQueryFrame(capture); убираю cvShowImage("postcapture", dst); то при запуске прога крашится. компилируется без ошибок. если я эту строку оставляю то все работает, только не нужное мне окно отрисовывается подскажите что с ней не так Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано March 5, 2014 Смотри в отладчике: где падает, почему падает, что за ошибка при падении, чему равны значения переменных... Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
brutalis 5 Жалоба Опубликовано April 16, 2014 еще раз приветствую. столкнулся с такой проблемой. есть код //************************Слежение за точками********http://recog.ru/library/opencv/opencvtrackingpoint.pdf //обработка событий с мыши IplImage *image = 0, *grey = 0, *prev_grey = 0, *pyramid = 0, *prev_pyramid = 0, *swap_temp; int win_size = 10; const int MAX_COUNT = 500; CvPoint2D32f* points[2] = {0,0}, *swap_points; char* status = 0; int count = 0; int need_to_init = 0; int night_mode = 0; int flags = 0; int add_remove_pt = 0; CvPoint pt; void on_mouse( int event, int x, int y, int flags, void* param ) { if( !image ) return; if( image->origin ) y = image->height - y; //************************* if( event == CV_EVENT_LBUTTONDOWN ) { //Если нажали левую кнопку мыши, то добавляем отслеживаемую точку pt = cvPoint(x,y); add_remove_pt = 1; printf("%d x %d\n " , x, y);//выводит координаты после закрытия программы }} //**************************** void MainWindow::on_point_detect_clicked() { int c,i, k; CvCapture* capture = cvCaptureFromCAM( 0); //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ if(capture == NULL)// Если камер не обнаружено proverka();assert( capture ); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, 320);//1280); cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT,240);//960); cvNamedWindow("capture", CV_WINDOW_AUTOSIZE); //Устанавливаем функцию обработчик мыши, сама функция находится выше cvSetMouseCallback( "capture", on_mouse, 0 ); while(true){// получаем кадр frame = cvQueryFrame( capture ); if( !image ) {/*Если изображение image не создано, то надо распределить все буферы. *Изображение не создано первоначально, *поэтому это всего навсего инициализация.*/ image = cvCreateImage( cvGetSize(frame), 8, 3 ); image->origin = frame->origin; grey = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_grey = cvCreateImage( cvGetSize(frame), 8, 1 ); pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); prev_pyramid = cvCreateImage( cvGetSize(frame), 8, 1 ); //Выделяем массивы под точки, судя по MAX_COUNT максимально у нас //может быть 500 точек points[0] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); points[1] = (CvPoint2D32f*)cvAlloc(MAX_COUNT*sizeof(points[0][0])); status = (char*)cvAlloc(MAX_COUNT); flags = 0;} //копирование и перевод в чёрно-белое изображение cvCopy( frame, image, 0 ); cvCvtColor( image, grey, CV_BGR2GRAY ); //Это для эффекта, когда вы нажимаете n изображение становится тёмным и //вы видите только перемещающиеся //назначенные вами точки if( night_mode ) cvZero( image ); if( need_to_init ) { //Это нужно для автоматической инициализации наблюдения - если вам лень //тыкать мышкой, то можно //запустить автоматическое сканирование изображения на факт выделения //подходящих точек IplImage* eig = cvCreateImage( cvGetSize(grey), 32, 1 ); IplImage* temp = cvCreateImage( cvGetSize(grey), 32, 1 ); double quality = 0.01; double min_distance = 10; count = MAX_COUNT; //определяет наиболее "сильные" углы изображения cvGoodFeaturesToTrack( grey, eig, temp, points[1], &count, quality, min_distance, 0, 3, 0, 0.04 ); //уточняет местоположение углов cvFindCornerSubPix( grey, points[1], count, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); //удаляет ненужные изображения cvReleaseImage( &eig ); cvReleaseImage( &temp ); add_remove_pt = 0;} else if( count > 0 ){ //Если есть хотя бы одна точка на экране, то за ней надо следить //Вычисляем оптический поток на факт поиска особенностей //points[0] - предыдущие точки points[1] - текущие точки cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid, points[0], points[1], count, cvSize(win_size,win_size), 3, status, 0, cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), flags ); flags |= CV_LKFLOW_PYR_A_READY; //перебираем все точки for( i = k = 0; i < count; i++ ){ //Если вы добавили новую точку нажатием мыши и она слишком близка к //предыдущей - просто удаляем её if( add_remove_pt ) {double dx = pt.x - points[1][i].x; double dy = pt.y - points[1][i].y; if( dx*dx + dy*dy <= 25 ) {add_remove_pt = 0; continue;}} if( !status[i] ) continue; points[1][k++] = points[1][i]; //Отображаем точку на экране cvCircle( image, cvPointFrom32f(points[1][i]), 3, CV_RGB(0,255,0), -1, 8,0);}count = k;} if( add_remove_pt && count < MAX_COUNT ) { //Если точка прошла процедуру проверки (см. выше), то добавляем её в буфер points[1][count++] = cvPointTo32f(pt); //уточняет местоположение углов для всех точек cvFindCornerSubPix( grey, points[1] + count - 1, 1, cvSize(win_size,win_size), cvSize(-1,-1), cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03)); add_remove_pt = 0;} CV_SWAP( prev_grey, grey, swap_temp ); CV_SWAP( prev_pyramid, pyramid, swap_temp ); //Меняем местами точки - новые становятся старыми на следующем шаге цикла CV_SWAP( points[0], points[1], swap_points ); need_to_init = 0;printf("%d\n " ,points[0]); // показываем cvShowImage("capture", image); // тянем frame на qlabel IplImage *img = cvCloneImage(image); QImage qimg; qimg = IplImage2QImage(img); // cvShowImage("Video", frame); ui->lbloriginal->setPixmap(QPixmap::fromImage(qimg)); cvReleaseImage(&img); image = cvQueryFrame(capture); char c = cvWaitKey(33); if (c == 27) {break;}} // нажата ESC switch( (char) c ) {case 'r':need_to_init = 1;break; case 'c':count = 0;break; case 'n':night_mode ^= 1;break; default:;} cvReleaseCapture( &capture ); cvDestroyWindow("capture");} int dig_key=0; int region_coordinates[10][4]; void myMouseCallback( int event, int x, int y, int flags, void* param) { IplImage* img = (IplImage*) param; switch( event ){ case CV_EVENT_MOUSEMOVE: printf("%d x %d\n " , x, y);//************************************* break; case CV_EVENT_LBUTTONDOWN: if (region_coordinates[dig_key][0] != 0 && region_coordinates[dig_key][1] != 0 && region_coordinates[dig_key][2] == 0 && region_coordinates[dig_key][3] == 0) { region_coordinates[dig_key][2]=x; region_coordinates[dig_key][3]=y; } if (region_coordinates[dig_key][0] == 0 && region_coordinates[dig_key][1] == 0) { region_coordinates[dig_key][0]=x; region_coordinates[dig_key][1]=y; } printf("%d x %dn", region_coordinates[dig_key][0], region_coordinates[dig_key][1]);printf("%d x %d\n " , x, y); break;//*************************************************************** case CV_EVENT_RBUTTONDOWN: break; case CV_EVENT_LBUTTONUP: break; } } помогите получить координаты точек.(чтобы воводились координаты в текущий момент в ремени) Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах