OPENCV 回调函数的使用

时间:2020-12-27 23:20:41
小弟在研究opencv用于图像识别的时候,在一个例子里面看到有关于回调函数使用的问题!
查了很多网上的资料,所采用的方法基本都是设置static静态函数的进行函数地址传递,但是这里有个问题就是我这个回调函数中另外还需要调用本身类的成员函数及较多的成员变量,这些成员变量也不太好照网上的办法全部设置为static变量,所以导致成员总是无法通过。还请那位朋友帮忙看看解决一下啊!!多谢了!
源程序如下:
#ifdef _CH_
#pragma package <opencv>
#endif

#ifndef _EiC
#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#include <math.h>
#include <string.h>
#endif

int thresh = 50;
IplImage* img = 0;
IplImage* img0 = 0;
CvMemStorage* storage = 0;
CvPoint pt[4];
const char* wndname = "Square Detection Demo";

double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 )
{
    return angle;
}
CvSeq* findSquares4( IplImage* img, CvMemStorage* storage )
{    
    return squares;
}
void drawSquares( IplImage* img, CvSeq* squares )
{      
}
void on_trackbar( int a )
{
    if( img )
        drawSquares( img, findSquares4( img, storage ) );
}
char* names[] = { "0.JPG","pic2.png", "pic3.png",
                  "pic4.png", "pic5.png", "pic6.png", 0 };

int main(int argc, char** argv)
{
    //cvCreateTrackbar函数为库函数,回调on_trackbar函数
   cvCreateTrackbar( "canny thresh", wndname, &thresh, 1000, on_trackbar );    
    return 0;
}

#ifdef _EiC
main(1,"squares.c");
#endif
//////////////////////////////////////////////////////////////////////////////////////////////////
///////以上为能够通过的标准C程序//////////以下为我修改后的程序,能通过编译,但是运行会程序崩溃////
class CImageIdenDoc : public CDocument
{
public:         
         void drawSquares( IplImage* img, CvSeq* squares );
CvSeq* findSquares( IplImage* img, CvMemStorage* storage );
double angle( CvPoint* pt1, CvPoint* pt2, CvPoint* pt0 );
}
class CImageIdenView : public CFormView
{
static void on_trackbar(int a);
}
void CImageIdenView::OnButton2() 
{
     CImageIdenDoc* pDoc = GetDocument();
     ASSERT_VALID(pDoc);

    int i=0, c=0;
    // create memory storage that will contain all the dynamic data
    pDoc->storage = cvCreateMemStorage(0);

 //   for( i = 0; i<pDoc->JPGNum; i++ )
for( i = 0; picnames[i]!="\0"; i++ )
    {
// load i-th image
        pDoc->m_cvImage = cvLoadImage( picnames[i], 1 );
if( c!= 1000 )
{
if( pDoc->m_cvImage == NULL)
{

CString s="Couldn't load "+picnames[i]+"!";
MessageBox(s);
}
         else
         {
         IplImage* imgforect;
         imgforect= cvCloneImage( pDoc->m_cvImage );
         // create window and a trackbar (slider) with parent "image" and set callback
         // (the slider regulates upper threshold, passed to Canny edge detector) 
          cvNamedWindow( pDoc->wndnamerect, CV_WINDOW_AUTOSIZE );
//自定义阈值
cvCreateTrackbar(pDoc->trackname, pDoc->wndnamerect, &pDoc->thresh, 256, on_trackbar);
         //on_trackbar函数的形式必须为void Foo(int)
// force the image processing
on_trackbar(0);
// wait for key.

// Also the function cvWaitKey takes care of event processing
         c = cvWaitKey(0);
release both images
cvReleaseImage( &imgforect );
// clear memory storage - reset free space position
cvClearMemStorage( pDoc->storage );
cvDestroyWindow(pDoc->wndnamerect);
}
     }
 }
void CImageIdenView::on_trackbar(int a)
{
CImageIdenDoc* pDoc;// = ::GetDocument();
    ASSERT_VALID(pDoc);
    AfxMessageBox("到这里了");//可以运行到这里
if(pDoc->m_cvImage != NULL)//这句话不能运行
{
AfxMessageBox("到这里了");//不能运行到这里
        pDoc->drawSquares(pDoc->m_cvImage, pDoc->findSquares(pDoc->m_cvImage, pDoc->storage ) );
}
}

void CImageIdenDoc::drawSquares(IplImage *img, CvSeq *squares)
{
}
double CImageIdenDoc::angle(CvPoint *pt1, CvPoint *pt2, CvPoint *pt0)//四边形的角度计算
{
    return angle;
}
CvSeq* CImageIdenDoc::findSquares(IplImage *img, CvMemStorage *storage)
{
}

4 个解决方案

#1


void CImageIdenView::on_trackbar(int a) 

CImageIdenDoc* pDoc;// = ::GetDocument(); 
  ASSERT_VALID(pDoc); 
    AfxMessageBox("到这里了");//可以运行到这里 
if(pDoc->m_cvImage != NULL)//这句话不能运行 

AfxMessageBox("到这里了");//不能运行到这里 
        pDoc->drawSquares(pDoc->m_cvImage, pDoc->findSquares(pDoc->m_cvImage, pDoc->storage ) ); 



你的pDoc是个非法的指针,当然不能运行了

#2


小心驴霸告你侵权哦

#3


我来学习学习

#4


看了好一会你的回复,终于看明白为什么了!!!

#1


void CImageIdenView::on_trackbar(int a) 

CImageIdenDoc* pDoc;// = ::GetDocument(); 
  ASSERT_VALID(pDoc); 
    AfxMessageBox("到这里了");//可以运行到这里 
if(pDoc->m_cvImage != NULL)//这句话不能运行 

AfxMessageBox("到这里了");//不能运行到这里 
        pDoc->drawSquares(pDoc->m_cvImage, pDoc->findSquares(pDoc->m_cvImage, pDoc->storage ) ); 



你的pDoc是个非法的指针,当然不能运行了

#2


小心驴霸告你侵权哦

#3


我来学习学习

#4


看了好一会你的回复,终于看明白为什么了!!!