如何使用线程通过 openCV 和 MFC 处理图像

Posted

技术标签:

【中文标题】如何使用线程通过 openCV 和 MFC 处理图像【英文标题】:How to use a thread to process image with openCV and MFC 【发布时间】:2016-03-25 09:30:56 【问题描述】:

我想使用线程来显示图像,但是当我尝试时,我得到以下信息:error : a nonstatic member reference must be relative to a specific object

错误发生在以下行:

ShowImage(Image1, IDC_ShowImg);

谁能帮我解决这个问题?谢谢。

这是我的代码:

.h 文件

class MFC_DMA : public CDialog

public:
    MFC_DMA(CWnd* pParent = NULL);   // standard constructor
    virtual ~MFC_DMA();
    // Dialog Data
    enum  IDD = IDD_MFC_DMA ;
private:
    CWinThread *worker_thread_;

protected:
    HICON m_hIcon;
    virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
    virtual BOOL OnInitDialog();
    DECLARE_MESSAGE_MAP();

public:
    afx_msg void OnBnClickedCancel();
    afx_msg void OnBnClickedOk();
    void ShowImage(IplImage * img, UINT ID);//imaging
    afx_msg void OnBnClickedButtonstart();//Start thread
    afx_msg void OnStnClickedShowimg2();//Picture control
    afx_msg void OnStnClickedShowimg();//Picture control
    static UINT MyThreadButton2(LPVOID LParam);//thread
;

.cpp 文件

void MFC_DMA::ShowImage(IplImage* img, UINT ID)

    CDC* pDC = GetDlgItem(ID)->GetDC(); 
    HDC hDC = pDC->GetSafeHdc();
    CRect rect;
    GetDlgItem(ID)->GetClientRect(&rect);
    int rw = rect.right - rect.left;
    int rh = rect.bottom - rect.top;
    int iw = img->width;
    int ih = img->height;
    int tx = (int)(rw - iw) / 2;
    int ty = (int)(rh - ih) / 2;
    SetRect(rect, 0, 0, 512, 512);
    CvvImage cimg;
    cimg.CopyOf(img);
    cimg.DrawToHDC(hDC, &rect);
    ReleaseDC(pDC);


    //Structure Thread2
    struct MyThreadInfo2
    
        HWND hWnd;
    
    Info2;// Global Variables
    BOOL Start_Stop = NULL;
    //Thread code
    UINT MFC_DMA::MyThreadButton2(LPVOID LParam)
    
        const int nSize2 = 32768;//I used PCI-e to receive data.
        const int width = 512;
        const int height = 512;
        const int channels = 1;
        const int step = 512 * 2; 
        CvSize img_size = cvSize(width, height);
        unsigned char *data = new unsigned char[nSize2];
        unsigned char *data2 = new unsigned char[nSize2];
        unsigned char *data_all = new unsigned char[nSize2 * 16];
        unsigned char *data_all2 = new unsigned char[nSize2 * 16];
        Image1 = cvCreateImageHeader(img_size, IPL_DEPTH_16U, channels);        
        Image2 = cvCreateImageHeader(img_size, IPL_DEPTH_16U, channels);
        cvCreateData(Image1);
        cvCreateData(Image2);
            
    while (Start_Stop)
        
            MyThreadInfo2 *pInfo2 = (MyThreadInfo2*)LParam; 
            MFC_DMA *hWnd = (MFC_DMA*)CWnd::FromHandle(pInfo2->hWnd);
            for (int i = 0; i < 16; i++)
            
                
                    for (int j = 0; j < nSize2; j++)
                        
                            data_all[nSize2*i + j] = 0;//Just want to test image
                                                       //0 is black
                            data_all2[nSize2*i + j] = 65535;//Just want to test                     image                                                       
                                                       //65535 is white
                        
                
                    cvSetData(Image1, data_all, step);
                    cvSetData(Image2, data_all2, step);
                    ShowImage(Image1, IDC_ShowImg);//have a error
                    ShowImage(Image2, IDC_ShowImg2); //have a error
            
            Image1 = NULL;
            Image2 = NULL;
            delete[] data;
            delete[] data_all;
            delete[] data2;
            delete[] data_all2;
        
        return(0);
    
    void MFC_DMA::OnBnClickedButtonstart()//Open the thread
    
            Info2.hWnd = this->m_hWnd;
            AfxBeginThread(MyThreadButton2, (LPVOID)&Info2);
            Start_Stop = TRUE;
    

【问题讨论】:

您正试图从静态函数MFC_DMA::MyThreadButton2(...) 调用非静态函数MFC_DMA::ShowImage(...)。 (您需要将指向MFC_DMA 实例的指针传递给静态线程函数,以便能够调用ShowImage)看起来您还试图从工作线程,AFAIK 不是一个好主意(例如,参见 this question) 谢谢你的回答。但我不知道如何从静态函数 MFC_DMA::MyThreadButton2(...) 调用非静态函数 MFC_DMA::ShowImage。你能给我一个例子?谢谢 我注意到您已经从传递给线程函数的窗口句柄创建了适当的指针(有点迂回,但没什么大不了的)。所以...hWnd-&gt;ShowImage(Image1, IDC_ShowImg); 谢谢 Dan Mašek。你解决了我的问题。谢谢。 【参考方案1】:

我注意到您已经从传递给线程函数的窗口句柄创建了适当的指针(有点迂回,但没什么大不了的)。所以...hWnd-&gt;ShowImage(Image1, IDC_ShowImg); 丹·马谢克

【讨论】:

以上是关于如何使用线程通过 openCV 和 MFC 处理图像的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV利用鼠标在如下图所示的MFC视频图像上画直线?

MFC+opencv+高斯背景前景提取图像显示问题

OpenCV与MFC实战之图像处理 样本采集小工具制作 c++MFC课程设计

未调用 MFC 的 CWinThread::PostThreadMessage 处理程序

基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)

基于Opencv和Mfc的图像处理增强库GOCVHelper(索引)