用OpenCv轉換原始圖像數據到wximage

接收數據部分好了,顯示圖片也會了,wxwi中wxBitmap有個構造函數原型如下:

wxBitmap::wxBitmap	(	const char 	bits[],
int 	width,
int 	height,
int 	depth = 1 
)	

這個函數可以從數組指針生成位圖,有了這個函數就可以把從串口接收的數據變成位圖。

理想總是美好的。。我搞了個數組測試了下,位圖深度設爲8,結果不顯示。。所以我像前面說的,嘗試了opencv庫,並且成功了,現在完成的部分有:

1.基本界面

2.能從我的USB口接收單片機發送來的數據,並顯示在wxctrltext中(文字模式與10進制模式)

3.能在wxwidgets中顯示圖片

4.能用opencv把char*指向的存儲數據轉換爲wxwidgets中的wximage(也就是可以實現opencv中圖片操作)

現在大致還有兩個問題要處理,1.選擇到底用opencv還是wxwidgets顯示圖片(想了想好像不用非要用wxwidgets顯示)2.對圖片數據的接收

對於第二點,因爲圖片數據判斷接收一副完整圖片後要進行處理,所以要對接收函數做一定處理。

第二點目前有三個思路1.自己用WIN32API實現接收2.重載ctb庫中的函數3.ctb庫中其他read函數封裝。

如果是第一種,可以用setcommmask設置串口關聯事件,可以用接收緩衝有數據來通知,判斷是否讀取完了一副圖,有讀幀頭和數數這種笨辦法或者結合一下。

第二種,函數自帶eos但是如果圖像兩個幀頭就不太方便,所以嘗試重載。第三種,判斷幀頭後調用讀取指定字節

先嚐試第二種,然後結合一下第一種。讀取是採用線程,主線程負責圖形界面,還有接收數據線程,處理數據線程等。

好吧,最後雖然差強人意,但大致的樣子如下:

    int mySerialPort::ReadAnImage(char*& databuf,char* eos)
    {
        DWORD Event;
        DWORD read;
        size_t readed;
        DCB dcb;
        char ch;
        PurgeComm(fd,PURGE_RXCLEAR);
        GetCommState(fd,&dcb);
        dcb.EvtChar=*eos;
        SetCommState(fd,&dcb);
        SetCommMask(fd,EV_RXFLAG);//設定串口接收事件
        while(1)
        {
            if(!WaitCommEvent(fd,&Event,&m_ov))//等待事件沒有立即發生
            {
                switch(GetLastError())
                {
                case ERROR_IO_PENDING: break;
                default : return -1;
                }
            }
        WaitForSingleObject(m_ov.hEvent,INFINITE);
        if(!GetOverlappedResult(fd,&m_ov,&read,false))
            return -2;
        ReadFile(fd,&ch,1,&read,&m_ov);
        if(ch==*eos)
            {
                ReadUntilEOS(databuf,&readed,eos,500);
                return 0;
            }
            PurgeComm(fd,PURGE_RXCLEAR);
        }

    }

這個函數放在線程中使用


改進版如下,吸收了前輩們的經驗:

char* mySerialPort::ReadBetweenEos(DWORD ReadBYteNum,char eos)
{
    char* buffer=new char[ReadBYteNum];
    DWORD Event;//wiatcommevent用
    DWORD read;//GetOverlappedResult,ReadFile用
    char ch;//校檢幀頭用
    Set_RXFLAG(&eos);
    while(1)
    {
        PurgeComm(fd,PURGE_RXCLEAR);
        if(!WaitCommEvent(fd,&Event,&m_ov))//等待事件沒有立即發生
        {
            switch(GetLastError())
            {
            case ERROR_IO_PENDING: break;
            default : continue;
            }
        }
    WaitForSingleObject(m_ov.hEvent,INFINITE);
    if(!GetOverlappedResult(fd,&m_ov,&read,false))
        continue;
    while(1)
    {
        ReadFile(fd,&ch,1,&read,&m_ov);
        if(ch==eos) break;
    }
    while(GetCacheByteNum()<(ReadBYteNum+1)) {Sleep(50);}//1是結尾幀頭
    ReadFile(fd,buffer,ReadBYteNum,&read,&m_ov);
    ReadFile(fd,&ch,1,&read,&m_ov);
    if(ch==eos) return buffer;
    else PurgeComm(fd,PURGE_RXCLEAR);
    }
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章