Razor 0 Жалоба Опубликовано November 16, 2011 Вероятно, это что-то довольно простое и очевидное, но я, в силу неопытности, не понимаю, как это пофиксить. Суть: при работе с видеофайлом в цикле напрямую изменяю изображение(маску), после чего на cvWaitKey вылезает ошибка сегментации. При работе с камерой все нормально, непрямое изменение изображения (через cvInRangeS, например) тоже ничего не ломает. В интернете нашел вот эту вот темку, но тогда я совсем ничего не понимаю. Код, например(бинарное пороговое преобразование, по сути) #include <opencv/highgui.h> #define threshold 120 CvCapture* capture = 0; IplImage* image = 0; IplImage* mask = 0; int getValue(IplImage* img, int x, int y){ uchar* ptr = (uchar*) (img->imageData + y * img->widthStep); return ptr[3*x+2]; } void setVal(IplImage* img, int x, int y, int val){ uchar* ptr = (uchar*) (img->imageData + y * img->widthStep); ptr[x]=val; } int main(int argc, char* argv[]) { capture = cvCaptureFromAVI("Flames.flv"); image = cvQueryFrame(capture); mask = cvCreateImage(cvGetSize(image),image->depth, 1); cvNamedWindow("original",CV_WINDOW_AUTOSIZE); cvNamedWindow("mask",CV_WINDOW_AUTOSIZE); cvMoveWindow("original", 0, 0); cvMoveWindow("mask", image->width+10, 0); cvZero(mask); cvShowImage("original",image); cvShowImage("mask",mask); while(true){ image=cvQueryFrame(capture); cvShowImage("original",image); for (int i=0; i<image->height; i++) for (int j=0; j<image->width; j++){ if (getValue(image, i, j)>threshold ){ setVal(mask, i, j, 255); } else setVal(mask, i, j, 0); } cvShowImage( "mask", mask ); char c = cvWaitKey(33); if (c == 27) { break; } } cvReleaseImage(&image); cvReleaseImage(&mask); cvDestroyAllWindows(); return 0; } Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано November 16, 2011 Да, проблема именно что простая и очевидная - ты перепутал индексы i и j. Вот и выход за границы. (В отладчике это же видно, почему, почему многие им не пользуются?!!) Ну и функции я бы написал так: uchar getValue(IplImage* img, int x, int y){ uchar* ptr = (uchar*) (img->imageData + y * img->widthStep); return ptr[img->nChannels * x + 2]; // Непонятно, зачем тут двойка } void setVal(IplImage* img, int x, int y, uchar val){ uchar* ptr = (uchar*) (img->imageData + y * img->widthStep); ptr[img->nChannels * x] = val; } 1 Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Razor 0 Жалоба Опубликовано November 16, 2011 О я дурак :/ Меня еще и то сбило, что по ссылке там все уж больно похоже было на мою проблему, да и с камерой все работало... Хотя там действительно изображение как-от деформировалось. А программа тестовая, поэтому и функции писал от констант, а не от реальных показателей. А двойка там для того, чтобы выдрать из HSV-изображения V-значение. Просто в данном случае я еще и конвертацию не написал, забыл. Энивей, спасибо! Ну и еще один глупый вопрос тогда уж. Храню историю кадров в виде просто массива IplImage*, в цикле обновляется: cvCopy(hist[1], hist[0]); cvCopy(hist[2], hist[1]); cvCopy(image, hist[2]);, но что-то она... не обновляется, в общем. Чисто внешне все элементы в hist и image совпадают. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах
Nuzhny 243 Жалоба Опубликовано November 16, 2011 Ну, я бы делал не копирование кучи кадров, а сдвиг указателей. Поделиться сообщением Ссылка на сообщение Поделиться на других сайтах