c++ - Qt OpenCV - SIGSEGV when displaying transformed frames -


i have app has pull frames video, transform 1 little, transform 1 lot, , simultaneously display them in gui. in worker thread, there's opencv loop:

while(1) {     cv::videocapture kalibrowanyplik;      kalibrowanyplik.open(kalibracja.tostdstring()); //open file url     int maxframes = kalibrowanyplik.get(cv_cap_prop_frame_count);     for(int i=0; i<maxframes; i++) //i thought crashed when finished reading first time around     {         cv::mat frame;         cv::mat gray;         cv::mat color;          kalibrowanyplik.read(frame);         cv::cvtcolor(frame, gray, cv_bgr2gray);         cv::cvtcolor(frame, color, cv_bgr2rgb);          qimage image((uchar*)color.data, color.cols, color.rows,qimage::format_rgb888);         qimage processedimage((uchar*)gray.data, gray.cols, gray.rows,qimage::format_indexed8);          emit progresschanged(image, processedimage);         qthread::msleep(50);     } } 

and how frames placed in gui

void mainwindow::onprogresschagned(qimage image, qimage processedimage) {     qpixmap processed = qpixmap::fromimage(processedimage);     processed = processed.scaledtoheight(379);     ui->labelhsv->clear();     ui->labelhsv->setpixmap(processed);      qpixmap original = qpixmap::fromimage(image); //debug points sigsegv here     original = original.scaledtoheight(379);     ui->labelkalibracja->clear();     ui->labelkalibracja->setpixmap(original); } 

the rgb image crashes, grayscale image never crashes (tested). why rgb image crashing?

edit: i've discovered if change msleep(50) msleep(100) executes perfectly. don't want that. need @ least 25 frames per second, 10 not acceptable... why cause sigsegv

standard issue. problem memory management! see other answer. in comments there is link.

so in code qimage doesn't copy , doesn't take ownership of memory of matrix. , later on when matrix destroyed , qimage tries access memory (qimage copied creating shallow copy) have segfault.


here code form this link (i've tweak bit), reason site has administration issues (some quota exceeded), why i'm pasting here.

inline qimage  cvmattoqimage( const cv::mat &inmat )    {       switch ( inmat.type() )       {          // 8-bit, 4 channel          case cv_8uc4:          {             qimage image( inmat.data, inmat.cols, inmat.rows, inmat.step, qimage::format_rgb32 );              qimage copy(image);             copy.bits(); //enforce deep copy             return copy;          }           // 8-bit, 3 channel          case cv_8uc3:          {             qimage image( inmat.data, inmat.cols, inmat.rows, inmat.step, qimage::format_rgb888 );              return image.rgbswapped();          }           // 8-bit, 1 channel          case cv_8uc1:          {             static qvector<qrgb>  scolortable;              // create our color table once             if ( scolortable.isempty() )             {                ( int = 0; < 256; ++i )                   scolortable.push_back( qrgb( i, i, ) );             }              qimage image( inmat.data, inmat.cols, inmat.rows, inmat.step, qimage::format_indexed8 );             image.setcolortable( scolortable );              qimage copy(image);             copy.bits(); //enforce deep copy             return copy;          }           default:             qwarning() << "asm::cvmattoqimage() - cv::mat image type not handled in switch:" << inmat.type();             break;       }        return qimage();    } 

your code should utilize functions that:

while(1) {     cv::videocapture kalibrowanyplik;      kalibrowanyplik.open(kalibracja.tostdstring()); //open file url     int maxframes = kalibrowanyplik.get(cv_cap_prop_frame_count);     for(int i=0; i<maxframes; i++) //i thought crashed when finished reading first time around     {         cv::mat frame;         cv::mat gray;          kalibrowanyplik.read(frame);         cv::cvtcolor(frame, gray, cv_bgr2gray);          qimage image(cvmattoqimage(frame));         qimage processedimage(cvmattoqimage(gray));          emit progresschanged(image, processedimage);         qthread::msleep(10); // bad see comments below     } } 

use of msleep in 95% cases bad! remove loop , create slot invoked signal qtimer.


Comments