Перейти к содержимому
Compvision.ru
brutalis

распознавание образов

Recommended Posts

доброго времени суток. возник такой вопрос.

есть ип-камера, я получаю с нее картинку. мне нужно, скажем, каждый 5 кадр с нее сверять с известной картиной(png или jpg). и если есть совпадение сообщить об этом как нибудь.(сигнал или функция)

подскажите пожалуйста как это реализовать. и где можно посмотреть описание с примерами.

зы. как вывести изображение на форму а не в отдельном окне

pps использую opencv и qt5

образцы картинок и исходники в архиве

camera.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте

Сопсотавление картинок можно сделать на основе особых точек 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/

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

проблема только в том, что как уже ранее говорилось, такой подход ищет только тот же самый объект, а не класс объекта, хотя в изначальном условии не уточнено.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Здравствуйте

Сопсотавление картинок можно сделать на основе особых точек 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/

спс. буду пробовать

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Всем доброго времени суток. по поводу моего предыдудщего поста о выводе 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();

}

проблемная часть закоментированна

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Может быть в том, что ты gray используешь? Конвертируй перед выводом в rgb.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Дык у меня вроде за клиент трова она строка гдч я в grey реревожу или я не прав?

Извинчюсь за ошибки и знаки поипинагия

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Какое ты изображение создаёшь? Серое:

dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
А выводишь какое? Цветное rgb:
QImage img(qImageBuffer, width, height, QImage::Format_RGB888);

Что-то мне подсказывает, что тут несостыковочка есть

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Какое ты изображение создаёшь? Серое:

dst = cvCreateImage( cvGetSize(frame), IPL_DEPTH_8U, 1 );
А выводишь какое? Цветное rgb:
QImage img(qImageBuffer, width, height, QImage::Format_RGB888);

Что-то мне подсказывает, что тут несостыковочка есть

Спасибо за разъяснение.

самостоятельно решить проблему вывода обработанного избражения не получается. подскажите что и где нужно исправить чтобы заработало.

спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Внутри функции IplImage2QImage проверяй iplImage->nChannels == 3

Если число каналов равно 1, то создавай трёхканальное изображение и делай в него cvCvtColor с параметром CV_GRAY2RGB. Потом это новое изображение и подавай сюда:

const uchar *qImageBuffer =(const uchar*)iplImage->imageData;

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Внутри функции IplImage2QImage проверяй iplImage->nChannels == 3

Если число каналов равно 1, то создавай трёхканальное изображение и делай в него cvCvtColor с параметром CV_GRAY2RGB. Потом это новое изображение и подавай сюда:

const uchar *qImageBuffer =(const uchar*)iplImage->imageData;

а можете расписать(примерчик или код), а то что то я совсем не соображаю

спасибо

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пишу навскидку:

//преобразуем 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();

}

  • Like 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Пишу навскидку:

//преобразуем 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();

}

Спасибо. помогло.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

тепрь у меня возникла следующая проблема. если я тут

//обработанное видео

                                    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);

то при запуске прога крашится. компилируется без ошибок. если я эту строку оставляю то все работает, только не нужное мне окно отрисовывается

подскажите что с ней не так

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Смотри в отладчике: где падает, почему падает, что за ошибка при падении, чему равны значения переменных...

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

еще раз приветствую.

столкнулся с такой проблемой.

есть код

//************************Слежение за точками********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;

  }

}

помогите получить координаты точек.(чтобы воводились координаты в текущий момент в ремени)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте учётную запись или войдите для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать учётную запись

Зарегистрируйтесь для создания учётной записи. Это просто!

Зарегистрировать учётную запись

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас на странице   0 пользователей

    Нет пользователей, просматривающих эту страницу

×