亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        GDI+與OpenCV在編程中混合使用的研究

        2015-09-18 05:54:02吳東謝國(guó)波蘇本卉
        現(xiàn)代計(jì)算機(jī) 2015年13期
        關(guān)鍵詞:方法

        吳東,謝國(guó)波,蘇本卉

        (1.中山大學(xué)附屬第一醫(yī)院繼續(xù)教育科,廣州510080;2.廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院,廣州510006)

        GDI+與OpenCV在編程中混合使用的研究

        吳東1,謝國(guó)波2,蘇本卉2

        (1.中山大學(xué)附屬第一醫(yī)院繼續(xù)教育科,廣州510080;2.廣東工業(yè)大學(xué)計(jì)算機(jī)學(xué)院,廣州510006)

        介紹兩種常用圖像接口GDI+和OpenCV的特點(diǎn)以及功能,主要闡述在Visual Studio開(kāi)發(fā)環(huán)境中使用GDI+和OpenCV結(jié)合混合使用處理圖像的思路并使用代碼實(shí)現(xiàn)。示例已通過(guò)上機(jī)調(diào)試,并投入實(shí)際使用。

        GDI+;OpenCV;混合;圖像

        0 引言

        OpenCV是一個(gè)基于(開(kāi)源)發(fā)行的跨平臺(tái)計(jì)算機(jī)視覺(jué)庫(kù),針對(duì)2D、3D圖像的處理提供了豐富的處理方法,主要應(yīng)用于物體識(shí)別、圖象分割、人臉識(shí)別、動(dòng)作識(shí)別、運(yùn)動(dòng)跟蹤、運(yùn)動(dòng)分析、機(jī)器視覺(jué)等領(lǐng)域,開(kāi)發(fā)效率比較高,常常是我們?cè)趯?shí)際應(yīng)用中處理圖像的首選[1]。而GDI+是微軟提供的一種圖形設(shè)備接口,主要用于2D圖像的繪制,其繪制圖形的功力非常強(qiáng)大。雖然圖像實(shí)際應(yīng)用中我們主要使用OpenCV進(jìn)行開(kāi)發(fā),但是一些細(xì)節(jié)地方難免需要用到GDI+的繪制功能,例如對(duì)一些圖片處理之后,需要在每張圖片上寫漢字。前面的圖像處理我們可使用OpenCV來(lái)完成,但是寫漢字就需要GDI+來(lái)完成。這就需要用到OpenCV和GDI+來(lái)混合使用,而混合使用的關(guān)鍵就是二者格式的轉(zhuǎn)化。

        1 GDI+與OpenCV圖片格式轉(zhuǎn)換原理的分析

        GDI+與OpenCV圖像類型的轉(zhuǎn)換是GDI+與OpenCV混合使用的關(guān)鍵,我們可以對(duì)GDI+與OpenCV表示圖像的類型的結(jié)構(gòu)和方法進(jìn)行分析。

        GDI+共包括三個(gè)圖像類:Image類、Bitmap類和Metafile類,其Metafile類主要用于處理矢量圖(不屬于本文討論范圍),Bitmap類主要表示光柵圖,Image是二者的父類。OpenCV中主要使用IplImage結(jié)構(gòu)體來(lái)創(chuàng)建和處理圖像,所以只需討論Bitmap與IplImage兩種格式并實(shí)現(xiàn)兩種格式的轉(zhuǎn)換即可。

        由于GDI+與OpenCV不存在強(qiáng)制互轉(zhuǎn),所以我們就采用另一種常用的轉(zhuǎn)換圖像格式的方法:就是把Bitmap或IplImage類型圖像轉(zhuǎn)換為Byte數(shù)據(jù)[2],然后構(gòu)造空白的Bitmap或IplImage類型的圖片,再把byte數(shù)據(jù)填充到該空白圖像中即可。

        1.1Bitmap到Byte的轉(zhuǎn)換

        把Bitmap轉(zhuǎn)換為二進(jìn)制會(huì)用到BitmapData這個(gè)類,使用BitmapData可以讀取圖片信息在內(nèi)存中的地址,BitmapData類中的Scan0表示圖片第0個(gè)像素的第0個(gè)分量在內(nèi)存的地址,BitmapData中Stride表示圖片一行像素的字節(jié)寬度,根據(jù)圖片的原點(diǎn)坐標(biāo)位置的不同可正可負(fù)。Windows系統(tǒng)的窗口坐標(biāo)原點(diǎn)為左上角,所以圖片在內(nèi)存中存放時(shí)順序是從左到右,從上到下,但當(dāng)圖片在窗口中顯示時(shí)卻有兩種坐標(biāo)。

        若圖片的原點(diǎn)坐標(biāo)與Windows相同在左上角,如圖1,則Sride為正數(shù),此時(shí)Scan0表示圖1中像素點(diǎn)a的地址,讀取順序是從左到右,從上到下,即a、b、c、d、e、f、g、h、i、j、k、l、m、n、o、p。

        若圖片坐標(biāo)原點(diǎn)在左下角,則像素點(diǎn)的順序如圖2,則此時(shí)Stride為負(fù)數(shù),此時(shí)Scan0表示圖1中像素點(diǎn)a的地址,由于memcpy方法拷貝數(shù)據(jù)是按照內(nèi)存中存儲(chǔ)順序進(jìn)行的,而此時(shí)圖片像素點(diǎn)在內(nèi)存中保存的順序?yàn)閙、n、o、p、i、j、k、l、e、f、g、h、a、b、c、d,所以應(yīng)調(diào)節(jié)讀取起始點(diǎn)a到m,讀取方式是從左到右,最先讀取圖像的最后一行。讀取信息后的圖片為原圖片關(guān)于x軸的反轉(zhuǎn)圖片,所以最后用OpenCV中cvFilp方法來(lái)再次反轉(zhuǎn)圖片,以得到圖片的正確顯示效果。

        圖1 原點(diǎn)在左上角時(shí)像素位置

        圖2 原點(diǎn)在左上角時(shí)像素位置

        1.2Ipllmage到Byte的轉(zhuǎn)換

        IplImage轉(zhuǎn)Byte相對(duì)于上面來(lái)說(shuō)比較簡(jiǎn)單,IplImage結(jié)構(gòu)中有imageDataOrigin和imageSize兩個(gè)參數(shù),其中imageDataOrigin表示圖像數(shù)據(jù)的起始地址,imageSize表示數(shù)據(jù)的長(zhǎng)度,用memcpy方法即可拷貝數(shù)據(jù)成Byte類型。

        1.3Byte到Ipllmage的轉(zhuǎn)換:

        IplImage結(jié)構(gòu)中存在imageData變量,表示IplImage類型圖像的數(shù)據(jù)。我們可以先用cvCreateImage方法創(chuàng)建一個(gè)和要轉(zhuǎn)換的Bitmap類型的圖片長(zhǎng)寬一樣的空白圖像,然后求出Byte中數(shù)據(jù)的長(zhǎng)度,用memcpy方法從Byte拷貝數(shù)據(jù)到imageData。最后根據(jù)Bitmap圖像原點(diǎn)坐標(biāo)的位置,判斷是否需要用IplImage的方法從cvFlip反轉(zhuǎn)圖像。

        1.4Byte到Ipllmage的轉(zhuǎn)換

        Byte到Bitmap同樣需要借組BitmapData,Bitmap中讀寫數(shù)據(jù)時(shí)需用LockBits來(lái)鎖定讀寫區(qū)域,并且LockBits方法中包含BitmapData類型的參數(shù),作用是保存要讀寫的數(shù)據(jù),而B(niǎo)itmapData可強(qiáng)轉(zhuǎn)為Byte類型,所以我們只需先新建一個(gè)Bitmap類型指針,鎖定Bitmap指針對(duì)象,關(guān)聯(lián)BitmapData對(duì)象,最后用memcpy方法拷貝Byte數(shù)據(jù)到BitmapData對(duì)象的Scan0變量中。

        2 GDI+與OpenCV在編程中混合使用的實(shí)現(xiàn)

        2.1GDI+與OpenCV類型呼轉(zhuǎn)函數(shù)的實(shí)現(xiàn)

        Bitmap*轉(zhuǎn)IplImage*代碼實(shí)現(xiàn):

        Ip lImage*BitmapToIplImage(Bitmap*pBitmap)

        {

        if(pBitmap)

        {

        BitmapData bmpData;

        Rect rect(0,0,pBitmap->GetW idth(),pBitmap->GetH-eight());

        pBitmap->LockBits(&rect,ImageLockModeRead,PixelFormat24bppRGB,&bmpData);

        BYTE*temp=NULL; If(bmpData.Stride>0)

        temp=(BYTE*)bmpData.Scan0;

        else

        temp=(BYTE*)bmpData.Scan0+bmpData.Stride* (pBitmap->GetHeight()-1);

        IplImage*p IplImg=cvCreateImage(cvSize(pBitmap-> GetWidth(),pBitmap->GetHeight()),IPL_DEPTH_8U,3);

        if(!p Ip lImg)

        {

        pBitmap->UnlockBits(&bmpData);

        return NULL;

        }

        memcpy(pIplImg->imageData,temp,abs(bmpData. Stride)*bmpData.Height);

        pBitmap->UnlockBits(&bmpData);

        if(bmpData.Stride<0)

        cvFlip(pIplImg,NULL,0);

        return pIplImg;

        }

        else

        return NULL;

        }

        函數(shù)思路過(guò)程:首先判斷圖像是否存在,新建對(duì)象bmpData保存Bitmap圖像數(shù)據(jù)信息,LockBits鎖定整個(gè)Bitmap中數(shù)據(jù)位置,然后讀取到temp中。創(chuàng)建lplImage對(duì)象pIplImg,把temp中數(shù)據(jù)拷貝到pIplImg中并解鎖pBitmap,最后返回填充好的lplImage圖片指針。

        IplImage*轉(zhuǎn)Bitmap*代碼實(shí)現(xiàn):

        Bitmap*IplImageToBitmap(IplImage*p Ip lImg)

        {

        if(p IplImg)

        {

        Bitmap*pBitmap=new Bitmap(pIplImg->width,p I-plImg->height,PixelFormat24bppRGB);

        if(!pBitmap)

        return NULL;

        BitmapData bmpData;

        Rect rect(0,0,p IplImg->width,p IplImg->height);

        pBitmap->LockBits(&rect,ImageLockModeWrite,PixelFormat24bppRGB,&bmpData);

        BYTE*pByte=(BYTE*)bmpData.Scan0;

        if(p IplImg->widthStep==bmpData.Stride)//likely

        memcpy(bmpData.Scan0,p IplImg->imageDataO-rigin,p IplImg->imageSize);

        pBitmap->UnlockBits(&bmpData);

        return pBitmap;

        }

        else

        return NULL;

        }

        函數(shù)思路過(guò)程:首先判斷圖像是否存在,然后用new方法新建一個(gè)長(zhǎng)寬和要轉(zhuǎn)換的IplImage圖像相等的Bitmap圖像,使用LockBits方法是為了鎖定整個(gè)Bitmap中數(shù)據(jù)位置然后等待數(shù)據(jù)的填充。memcpy用于拷貝填充bmpData,Scan0表示數(shù)據(jù)矩陣在內(nèi)存中的地址,imageDataOrigin表示IplImage類型圖片中數(shù)據(jù)的起始位置,imageSize表示數(shù)據(jù)的長(zhǎng)度,把IplImage中數(shù)據(jù)拷貝到Bitmap中后用UnlockBits解鎖區(qū)域,最后返回填充好的Bitmap圖片指針。

        2.2互轉(zhuǎn)函數(shù)的測(cè)試

        本測(cè)試主要是驗(yàn)證圖片類型互轉(zhuǎn)后可不可以正確使用轉(zhuǎn)換后的圖片指針,測(cè)試中使用顯示圖片這個(gè)功能進(jìn)行驗(yàn)證。

        首先,用IplImage類型載入C盤下的圖片test.jpg,然后用IplImageToBitmap函數(shù)把IplImage圖片轉(zhuǎn)為Bitmap類型,然后用Draw Image函數(shù)顯示圖片,代碼如下:

        CDC*pDC=GetDC();

        Graphics graph(pDC->GetSafeHdc());

        IplImage*pImage=cvLoad Image("c:\test.jpg",1);

        Bitmap*img=IplImageToBitmap(p Image);

        graph.DrawImage(img,0,0);

        程序執(zhí)行完后可得結(jié)果(下圖):

        圖3 轉(zhuǎn)換后結(jié)果

        然后,用Bitmap類型載入C盤下的圖片test.jpg,然后用BitmapToIplImage函數(shù)把Bitmap圖片轉(zhuǎn)為I-plImage類型,調(diào)OpenCV的cvShow Image函數(shù)顯示圖片,代碼如下:

        CDC*pDC=GetDC();

        Bitmap*img=Bitmap::FromFile(L"c:\test.jpg");

        IplImage*p Image=BitmapToIplImage(img);

        cvShowImage("圖片",pImage);

        程序執(zhí)行完后可得結(jié)果(圖4)。

        2.3測(cè)試結(jié)論

        由以上測(cè)試可知,GDI+和OpenCV中主要的圖片類Bitmap和IplImage類型相互轉(zhuǎn)換后均能正確地顯示圖片,即在實(shí)際的開(kāi)發(fā)應(yīng)用過(guò)程中可以針對(duì)不同情況靈活地選擇其一進(jìn)行使用,大大提高了代碼的靈活性和編程效率。

        圖4 轉(zhuǎn)換后結(jié)果

        3 結(jié)語(yǔ)

        GDI+與OpenCV都具有豐富的圖像操作及處理方法,實(shí)際操作中可能會(huì)反復(fù)用到兩個(gè)庫(kù)的轉(zhuǎn)換,本文提供的算法能夠方便地實(shí)現(xiàn)它們各自支持的類型的轉(zhuǎn)換,不需要去保存中間圖像數(shù)據(jù),可以使用戶能夠方便地在實(shí)際應(yīng)用中根據(jù)需要結(jié)合二者各自的長(zhǎng)處來(lái)設(shè)計(jì)程序,使得圖像處理的工作變得事半功倍。

        [1]左飛.數(shù)字圖像處理技術(shù)詳解與Visual C++實(shí)踐.北京:電子工業(yè)出版社.2014(3):157~242

        [2]高守傳,劉書志,姚領(lǐng)田等.VC++實(shí)踐與提高——數(shù)字圖像處理與工程應(yīng)用篇.北京:中國(guó)鐵道出版社.2006(1):5~17

        [3]劉瑞楨,于仕琪.OpenCV教程——基礎(chǔ)篇.北京:北京航空航天出版社,2007:76~385

        [4]Chand M.GDI+圖形程序設(shè)計(jì).北京:電子工業(yè)出版社,2005:1~325

        GDI+;OpenCV;Mixed;Images

        Research on the Mixed Use of GDI+and OpenCV in Programm ing

        WU Dong1,XIE Guo-bo2,SU Ben-hui2

        (1.Department of Education,the First Affiliated Hospital of SUN Yat-sen University,Guangzhou 510080;2.College of Computer,Guangdong University of Technology,Guangzhou 510006)

        Introduces the two common interface of GDI+and OpenCV image features and functions,mainly elaborates the idea of using GDI+and OpenCV mixing processing image in the Visual Studio development environment and then implementing code.The example has passed the debugging and put in actual application.

        1007-1423(2015)16-0082-04

        10.3969/j.issn.1007-1423.2015.16.019

        吳東(1974-),男,海南人,本科,研究實(shí)習(xí)員,研究方向?yàn)樾畔⒒芾?/p>

        謝國(guó)波(1977-),男,廣東五華人,博士,教授,研究方向?yàn)樵朴?jì)算與大數(shù)據(jù)、混沌保密通信、低碳制造數(shù)據(jù)智能化處理

        蘇本卉(1991-),男,河南安陽(yáng)人,碩士研究生,研究方向?yàn)榛煦绫C芡ㄐ?/p>

        2015-04-07

        2015-05-15

        猜你喜歡
        方法
        中醫(yī)特有的急救方法
        中老年保健(2021年9期)2021-08-24 03:52:04
        高中數(shù)學(xué)教學(xué)改革的方法
        化學(xué)反應(yīng)多變幻 “虛擬”方法幫大忙
        變快的方法
        兒童繪本(2020年5期)2020-04-07 17:46:30
        學(xué)習(xí)方法
        可能是方法不對(duì)
        用對(duì)方法才能瘦
        Coco薇(2016年2期)2016-03-22 02:42:52
        最有效的簡(jiǎn)單方法
        山東青年(2016年1期)2016-02-28 14:25:23
        四大方法 教你不再“坐以待病”!
        Coco薇(2015年1期)2015-08-13 02:47:34
        賺錢方法
        精品一级一片内射播放| 国产女主播福利一区在线观看| 四虎影院在线观看| 色欲av一区二区久久精品| 中文字幕第一页亚洲观看 | 欧美成免费a级毛片| 亚洲日韩欧洲无码av夜夜摸| 亚洲国产成人精品女人久久久 | 成l人在线观看线路1| 久久无码高潮喷水| 亚洲AV无码成人精品区网页| 国产三级国产精品三级在专区| 一区二区在线观看视频亚洲| 亚洲精品一区三区三区在线| 99无码精品二区在线视频| 久久亚洲私人国产精品va| 亚洲av无码一区二区乱子伦as| 精品久久久久久无码不卡| 蜜桃视频免费在线视频| 海外华人在线免费观看| 久久久亚洲欧洲日产国码二区 | 亚洲乱码日产精品bd在线观看| 色综合另类小说图片区| 国产精品自拍首页在线观看| 亚洲av成人波多野一区二区| 国产午夜在线视频观看| 国产啪亚洲国产精品无码| 久久人人爽人人爽人人av东京热| 无码高潮久久一级一级喷水| 97久久国产精品成人观看| 日韩av无码一区二区三区| 玩弄放荡人妻少妇系列视频| 久99久热只有精品国产男同| 精品一区二区三区在线观看l| 国产av三级精品车模| 野花香社区在线视频观看播放| 国产高潮刺激叫喊视频| 久久永久免费视频| 国产日韩亚洲中文字幕| 国产91会所女技师在线观看| 欧美成人国产精品高潮|