Access Violation

Компьютерное зрение, OpenCV

Access Violation

Сообщение Luminar » 27 окт 2011, 15:52

Прои запуске кода в Release режиме выдает:
"Unhandled exception at 0x00411b05 in ImageAnalysis.exe: 0xC0000005: Access violation reading location 0x0000001c."
В Debug режиме просто посылает отчеты.
Код функции main:
Код: Выделить всё
int main (int argc, char **argv)
{
   //char deb;
   //ShowImage("test.jpg");
   //ShowVideo("test.avi");
   RGB ans;
   CvCapture* vid;
   vid=cvCaptureFromFile("test.avi");
   int frames=GetFramesCount(vid);
   int width=GetVideoWidth(vid);
   int height=GetVideoHeight(vid);
   printf("width=%d   height=%d   frames=%d\n",width,height,frames);
   for(int i=0;i<width;i++)
      for(int j=0;j<height;j++)
         for(int k=0;k<frames;k++){
            //
            ans=GetFramePixel(vid,i,j,k);
            printf("R=%d   G=%d   B=%d\n",ans.R,ans.G,ans.B);
            //scanf("%c",deb);
         }

   return 0;
}

Проход по всем пикселям всех фреймов видео, и вывод значений RGB на экран.
Когда я тестировал этот пример на *.avi файле (10 кадров в секунду), имеющем 81 кадр, проблема возникала при переходе к 81му. Если его наличие само по себе не баг, значит программа не работает,
когда кол-во кадров в видео не кратно кол-ву кадров в секунду. // Уже не актуально, т.к.
Код: Выделить всё
int GetFramesCount(CvCapture* capture)
{
   int frames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
   frames=(frames/(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS))*(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
   return frames;
}

не решает проблему в другом случае.
Как исправить эту ошибку?
Весь код:
Код: Выделить всё
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>

//img
struct RGB{
   int R;
   int G;
   int B;
};
void ShowImage(const char* imagename);
RGB GetPixel(IplImage *image, int x, int y);
int GetImageWidth(IplImage *image);
int GetImageHeight(IplImage *image);

//avi
void ShowVideo(const char* videoname);
int GetFramesCount(CvCapture* capture);
int GetVideoWidth(CvCapture* capture);
int GetVideoHeight(CvCapture* capture);
RGB GetFramePixel(CvCapture* capture, int x, int y, int frameCount);

//main
int main (int argc, char **argv)
{
   //char deb;
   //ShowImage("test.jpg");
   //ShowVideo("test.avi");
   RGB ans;
   CvCapture* vid;
   vid=cvCaptureFromFile("test.avi");
   int frames=GetFramesCount(vid);
   int width=GetVideoWidth(vid);
   int height=GetVideoHeight(vid);
   printf("width=%d   height=%d   frames=%d\n",width,height,frames);
   for(int i=0;i<width;i++)
      for(int j=0;j<height;j++)
         for(int k=0;k<frames;k++){
            //
            ans=GetFramePixel(vid,i,j,k);
            printf("R=%d   G=%d   B=%d\n",ans.R,ans.G,ans.B);
            //scanf("%c",deb);
         }

   return 0;
}

//img
void ShowImage(const char* imagename)
{
   IplImage *image = cvLoadImage(imagename, 1);

   GetPixel(image, image->width-1, image->height-1);
   cvNamedWindow("window", CV_WINDOW_AUTOSIZE);

   cvShowImage("window", image);

   cvWaitKey(0);
   
   cvReleaseImage(&image);
   cvDestroyWindow("window");
}

RGB GetPixel(IplImage *image, int x, int y)
{
   RGB rgb;
   if (image->dataOrder == IPL_DATA_ORDER_PIXEL){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width)*3];
         unsigned char g = image->imageData[(x+y*image->width)*3+1];
         unsigned char b = image->imageData[(x+y*image->width)*3+2];

         rgb.R=b; rgb.G=g; rgb.B=r;
      }
   }
   else if (image->dataOrder == IPL_DATA_ORDER_PLANE){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width*3)];
         unsigned char g = image->imageData[(x+image->width+y*image->width*3)];
         unsigned char b = image->imageData[(x+image->width*2+y*image->width*3)];

         rgb.R=r; rgb.G=g; rgb.B=b;
      }
   }
   return rgb;
}

int GetImageWidth(IplImage *image)
{
   return image->width;
}

int GetImageHeight(IplImage *image)
{
   return image->height;
}

//video
void ShowVideo(const char* videoname)
{
   IplImage* frame =0;
   cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
   CvCapture* capture = cvCreateFileCapture( videoname );
   //int n=GetFramesCount(capture);
   //cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, n);
   while(1){
      frame = cvQueryFrame( capture );
      if( !frame ) {
            break;
      }
      cvShowImage("video", frame);

      char c = cvWaitKey(33);
      if (c == 27) { // если нажата ESC - выходим
            break;
      }
   }
   
   cvReleaseCapture( &capture );
   cvDestroyWindow("video");

}

int GetFramesCount(CvCapture* capture)
{
   int frames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
   //frames--;
   return frames;
}

RGB GetFramePixel(CvCapture* capture, int x, int y, int frameCount)
{
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameCount);
   IplImage* image =0;
   image = cvQueryFrame( capture );

   RGB rgb;
   if (image->dataOrder == IPL_DATA_ORDER_PIXEL){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width)*3];
         unsigned char g = image->imageData[(x+y*image->width)*3+1];
         unsigned char b = image->imageData[(x+y*image->width)*3+2];

         rgb.R=b; rgb.G=g; rgb.B=r;
      }
   }
   else if (image->dataOrder == IPL_DATA_ORDER_PLANE){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width*3)];
         unsigned char g = image->imageData[(x+image->width+y*image->width*3)];
         unsigned char b = image->imageData[(x+image->width*2+y*image->width*3)];

         rgb.R=r; rgb.G=g; rgb.B=b;
      }
   }
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, 0);

   return rgb;
}

int GetVideoWidth(CvCapture* capture)
{
   int w = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
   return w;
}

int GetVideoHeight(CvCapture* capture)
{
   int h = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
   return h;
}

Часть, которая глючит:
Код: Выделить всё
struct RGB{
   int R;
   int G;
   int B;
};
RGB GetFramePixel(CvCapture* capture, int x, int y, int frameCount)
{
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameCount);
   IplImage* image =0;
   image = cvQueryFrame( capture );

   RGB rgb;
   if (image->dataOrder == IPL_DATA_ORDER_PIXEL){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width)*3];
         unsigned char g = image->imageData[(x+y*image->width)*3+1];
         unsigned char b = image->imageData[(x+y*image->width)*3+2];

         rgb.R=b; rgb.G=g; rgb.B=r;
      }
   }
   else if (image->dataOrder == IPL_DATA_ORDER_PLANE){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width*3)];
         unsigned char g = image->imageData[(x+image->width+y*image->width*3)];
         unsigned char b = image->imageData[(x+image->width*2+y*image->width*3)];

         rgb.R=r; rgb.G=g; rgb.B=b;
      }
   }
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, 0);

   return rgb;
}

UPD: В консоли выдает строчку
HIGHGUI ERROR: AVI: Could not seek to position 0.000
В коде VS указывает на
if (image->dataOrder == IPL_DATA_ORDER_PIXEL).
В дебаге, в значении этого параметра: dataOrder CXX0030: Error: expression cannot be evaluated.
Протестировал все на видео, в котором 30 секунд.
(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS)=14
(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT)=451
14*30=420
[420;433]<451.
А валится все на 62м фрейме. :sh_ok:
Luminar
 
Сообщения: 2
Зарегистрирован: 27 окт 2011, 15:37
programming: c/c++

Re: Access Violation

Сообщение noonv » 28 окт 2011, 19:33

не забываем проверять возвращаемые значения и получаемые параметры :-):
например, после
Код: Выделить всё
image = cvQueryFrame( capture );

вставить проверку
Код: Выделить всё
if(image)

:mi_ga_et:
Аватара пользователя
noonv
Администратор
 
Сообщения: 556
Зарегистрирован: 05 май 2011, 15:44
Откуда: Калининград
programming: С++

Re: Access Violation

Сообщение Luminar » 29 окт 2011, 00:30

Проблема с прерыванием исполнения решена. Спасибо! :dan_ser:
Но если в видеозаписи 100 на 100 пикселей 81 фрейм, то всего в ней 810000 пикселей. А в результате
Код: Выделить всё
if(image)
   rgb=GetPixel(image,x,y);
else{
   rgb.R=-1;
   rgb.B=-1;
   rgb.G=-1;
}

и отсечения минус единиц в цикле, как в коде ниже, проход осуществляется только по 800000. Оставшиеся не существуют в видео? :ne_vi_del:

Код: Выделить всё
#include "cv.h"
#include "highgui.h"
#include <stdlib.h>
#include <stdio.h>

//img
struct RGB{
   int R;
   int G;
   int B;
};
void ShowImage(const char* imagename);
RGB GetPixel(IplImage *image, int x, int y);
int GetImageWidth(IplImage *image);
int GetImageHeight(IplImage *image);

//avi
void ShowVideo(const char* videoname);
int GetFramesCount(CvCapture* capture);
int GetVideoWidth(CvCapture* capture);
int GetVideoHeight(CvCapture* capture);
RGB GetFramePixel(CvCapture* capture, int x, int y, int frameCount);

//main
int main (int argc, char **argv)
{
   //char deb;
   //ShowImage("test.jpg");
   //ShowVideo("test.avi");
   RGB ans;
   int counter=0;
   CvCapture* vid;
   vid=cvCaptureFromFile("test.avi");
   int frames=GetFramesCount(vid);
   int width=GetVideoWidth(vid);
   int height=GetVideoHeight(vid);
   int all=width*height*frames;
   printf("width=%d   height=%d   frames=%d  all=%d\n",width,height,frames,all);
   for(int i=0;i<width;i++)
      for(int j=0;j<height;j++)
         for(int k=0;k<frames;k++){
            //
            ans=GetFramePixel(vid,i,j,k);
            if(ans.R==-1)
               break;
            counter++;
            printf("%d out of %d\n",counter,all);
            //printf("R=%d   G=%d   B=%d  at %d frame\n",ans.R,ans.G,ans.B,k);
            //scanf("%c",deb);
         }
   printf("%d total\n",counter);
   return 0;
}

//img
void ShowImage(const char* imagename)
{
   IplImage *image = cvLoadImage(imagename, 1);

   GetPixel(image, image->width-1, image->height-1);
   cvNamedWindow("window", CV_WINDOW_AUTOSIZE);

   cvShowImage("window", image);

   cvWaitKey(0);
   
   cvReleaseImage(&image);
   cvDestroyWindow("window");
}

RGB GetPixel(IplImage *image, int x, int y)
{
   RGB rgb;
   if (image->dataOrder == IPL_DATA_ORDER_PIXEL){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width)*3];
         unsigned char g = image->imageData[(x+y*image->width)*3+1];
         unsigned char b = image->imageData[(x+y*image->width)*3+2];

         rgb.R=b; rgb.G=g; rgb.B=r; // фикс ...
      }
   }
   else if (image->dataOrder == IPL_DATA_ORDER_PLANE){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width*3)];
         unsigned char g = image->imageData[(x+image->width+y*image->width*3)];
         unsigned char b = image->imageData[(x+image->width*2+y*image->width*3)];

         rgb.R=r; rgb.G=g; rgb.B=b;
      }
   }
   return rgb;
}

int GetImageWidth(IplImage *image)
{
   return image->width;
}

int GetImageHeight(IplImage *image)
{
   return image->height;
}

//video
void ShowVideo(const char* videoname)
{
   IplImage* frame =0;
   cvNamedWindow("video", CV_WINDOW_AUTOSIZE);
   CvCapture* capture = cvCreateFileCapture( videoname );
   //int n=GetFramesCount(capture);
   //cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, n);
   while(1){
      frame = cvQueryFrame( capture );
      if( !frame ) {
            break;
      }
      cvShowImage("video", frame);

      char c = cvWaitKey(33);
      if (c == 27) { // если нажата ESC - выходим
            break;
      }
   }
   
   cvReleaseCapture( &capture );
   cvDestroyWindow("video");

}

int GetFramesCount(CvCapture* capture)
{
   int frames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
   //frames=(frames/(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS))*(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
   printf("%dFPS\n",(int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS));
   return frames;
}

RGB GetFramePixel(CvCapture* capture, int x, int y, int frameCount)
{
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frameCount);
   IplImage* image =0;
   image = cvQueryFrame( capture );
   //IplImage* gym = cvCreateImage(cvSize(image->width,image->height),IPL_DEPTH_8U, 1);
   //cvConvertImage(image,gym,0);
   RGB rgb;
   /*if (image->dataOrder == IPL_DATA_ORDER_PIXEL){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width)*3];
         unsigned char g = image->imageData[(x+y*image->width)*3+1];
         unsigned char b = image->imageData[(x+y*image->width)*3+2];

         rgb.R=b; rgb.G=g; rgb.B=r;
      }
   }
   else if (image->dataOrder == IPL_DATA_ORDER_PLANE){
      if(image->nChannels == 3){
         unsigned char r = image->imageData[(x+y*image->width*3)];
         unsigned char g = image->imageData[(x+image->width+y*image->width*3)];
         unsigned char b = image->imageData[(x+image->width*2+y*image->width*3)];

         rgb.R=r; rgb.G=g; rgb.B=b;
      }
   }*/
   if(image)
      rgb=GetPixel(image,x,y);
   else{
      rgb.R=-1;
      rgb.B=-1;
      rgb.G=-1;
   }
   cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, 0);

   return rgb;
}

int GetVideoWidth(CvCapture* capture)
{
   int w = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
   return w;
}

int GetVideoHeight(CvCapture* capture)
{
   int h = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
   return h;
}
Luminar
 
Сообщения: 2
Зарегистрирован: 27 окт 2011, 15:37
programming: c/c++


Вернуться в Компьютерное зрение

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 6

© 2009-2017 |  О проекте  |  Политика Конфиденциальности  |