基于Qt的OpenCV圖像處理1:對比度金闽、亮度纯露、平滑濾波、縮放旋轉(zhuǎn)以及人臉識別;

本系列文章我將為大家介紹一些基于Qt的OpenCV圖像處理實現(xiàn)代芜。

Qt得益于信號和槽的抽象概念埠褪,使得在此利用OpenCV實現(xiàn)圖像處理并不困難。只需要簡單的初始化挤庇,就可以使用它了钞速。

初始化

首先在Qt項目的.pro文件下添加語句導(dǎo)入OpenCV庫:

12345INCLUDEPATH += D:/Work/Code/Learn/OpenCV01/Qt/opencv-mingw-3.4.5/include\? ? ? ? ? ? ? D:/Work/Code/Learn/OpenCV01/Qt/opencv-mingw-3.4.5/include/opencv\? ? ? ? ? ? ? D:/Work/Code/Learn/OpenCV01/Qt/opencv-mingw-3.4.5/include/opencv2LIBS += -L D:/Work/Code/Learn/OpenCV01/Qt/opencv-mingw-3.4.5/lib/libopencv_*.a

接著聲明三個基本槽:

123void initMainWindow();? //初始化void imgShow();? ? ? //圖像顯示Mat myImg;? ? ? ? //圖像存放變量

最后編寫基本代碼段:

12345678910111213141516//初始化void MainWindow::initMainWindow(){? ? QString imgPath="test.jpg";? ? Mat imgData=imread(imgPath.toLatin1().data());? ? cvtColor(imgData,imgData,COLOR_BGR2RGB);? ? myImg=imgData;? ? myQImg=QImage((const unsigned char*)(imgData.data),imgData.cols,imgData.rows,QImage::Format_RGB888);? ? imgShow();}myImg=imgData;:賦給myImg全局變量待處理,myImg是點(diǎn)陣類型的以圖像形式緩存圖片嫡秕。//將圖像通過QPixmap到Label控件上顯示void MainWindow::imgShow(){? ? ui->viewLabel->setPixmap(QPixmap::fromImage(myQImg.scaled(ui->viewLabel->size(),Qt::KeepAspectRatio)));}

至此就可以開始編寫你程序的其它功能了渴语。

對比度與亮度

https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Contrast_Brightness

1234567891011121314151617181920212223void MainWindow::imgProc(float con,int bri){? ? Mat imgSrc=myImg;? ? Mat imgDst=Mat::zeros(imgSrc.size(),imgSrc.type());? ? imgSrc.convertTo(imgDst,-1,con,bri);? ? myQImg=QImage((const unsigned char*)(imgDst.data),imgDst.cols,imgDst.rows,QImage::Format_RGB888);? ? imgShow();}void MainWindow::on_contrastVerticalSlider_sliderMoved(int position){? ? imgProc(position/33.3,0);}void MainWindow::on_contrastVerticalSlider_valueChanged(int value){? ? imgProc(value/33.3,0);}void MainWindow::on_brightnessVerticalSlider_sliderMoved(int position){? ? imgProc(1.0,position);}void MainWindow::on_brightnessVerticalSlider_valueChanged(int value){? ? imgProc(1.0,value);}

imgSrc.convertTo(imgDst,-1,con,bri);:

OpenCV增強(qiáng)圖片使用的是點(diǎn)算子,即用常數(shù)對每個像素點(diǎn)執(zhí)行乘法和加法的復(fù)合運(yùn)算:g(i,j)=af(i,j)+b昆咽。

式中驾凶,f(i,j)代表一個原圖的像素點(diǎn)牙甫;a是增益參數(shù),控制圖片對比度狭郑;b是偏值參數(shù)腹暖,控制圖片亮度;而g(i,j)則表示經(jīng)處理后的對應(yīng)像素點(diǎn)翰萨。這兩個參數(shù)分別對應(yīng)程序中的變量con和bri脏答,執(zhí)行時將它們的值傳入OpenCV的convertTo()方法,在其內(nèi)部就會對圖片上的每個點(diǎn)均勻用上式的算法進(jìn)行處理變換亩鬼。

平滑濾波

https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Blur_Gaussian_Median_Bilateral_1

均值濾波:

123Mat imgDst1=imgSrc.clone();? ? for(int i=1;i<ker;i+=2) blur(imgSrc,imgDst1,Size(i,i),Point(-1,-1));? ? myBlurQImg=QImage((const unsigned char*)(imgDst1.data),imgDst1.cols,imgDst1.rows,QImage::Format_RGB888);

高斯濾波:

123Mat imgDst2=imgSrc.clone();? ? for(int i=1;i<ker;i+=2) GaussianBlur(imgSrc,imgDst2,Size(i,i),0,0);? ? myGaussianQImg=QImage((const unsigned char*)(imgDst2.data),imgDst2.cols,imgDst2.rows,QImage::Format_RGB888);

中值濾波:

123Mat imgDst3=imgSrc.clone();? ? for(int i=1;i<ker;i+=2) medianBlur(imgSrc,imgDst3,i);? ? myMedianQImg=QImage((const unsigned char*)(imgDst3.data),imgDst3.cols,imgDst3.rows,QImage::Format_RGB888);

雙邊濾波:

123Mat imgDst4=imgSrc.clone();? ? for(int i=1;i<ker;i+=2) bilateralFilter(imgSrc,imgDst4,i,i*2,i/2);? ? myBilateralQImg=QImage((const unsigned char*)(imgDst4.data),imgDst4.cols,imgDst4.rows,QImage::Format_RGB888);

旋轉(zhuǎn)與縮放

https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_Zoom_Rotate_1

123456789101112void MainWindow::imgProc(float ang, float sca){? ? Point2f srcMatrix[3];? ? Point2f dstMatrix[3];? ? Mat imgRot(2,3,CV_32FC1);? ? Mat imgSrc=myImg;? ? Mat imgDst;? ? Point centerPoint=Point(imgSrc.cols/2,imgSrc.rows/2);? ? imgRot=getRotationMatrix2D(centerPoint,ang,sca);? ? warpAffine(imgSrc,imgDst,imgRot,imgSrc.size());? ? myQImg=QImage((const unsigned char*)(imgDst.data),imgDst.cols,imgDst.rows,QImage::Format_RGB888);? ? imgShow();}

該方法接收兩個參數(shù)殖告,皆為單精度實型,ang表示旋轉(zhuǎn)角度(正為順時針雳锋、負(fù)為逆時針)黄绩,sca表示縮放率(大于1為放大、小于1為縮小)玷过。

imgRot=getRotationMatrix2D(centerPoint,ang,sca);:

OpenCV內(nèi)部用仿射變換算法來實現(xiàn)圖片的旋轉(zhuǎn)縮放爽丹。它需要三個參數(shù):

(1)旋轉(zhuǎn)圖片所要圍繞的中心;

(2)旋轉(zhuǎn)的角度辛蚊,在OpenCV中逆時針角度為正值粤蝎,反之為負(fù)值;

(3)縮放因子(可選)袋马,在本例中分別對應(yīng)centerPoint初澎、ang和sca參數(shù)值。

任何一個仿射變換都能表示為向量乘以一個矩陣(線性變換)再加上另一個向量(平移)虑凛,研究表明碑宴,不論是對圖片的旋轉(zhuǎn)還是縮放操作,本質(zhì)上都是對其每個像素施加了某種線性變換桑谍,如果不考慮平移延柠,實際上也就是一個仿射變換。因此霉囚,變換的關(guān)鍵在于求出變換矩陣捕仔,這個矩陣實際上代表了變換前后兩張圖片之間的關(guān)系。這里用OpenCV的getRotationMatrix2D()方法來獲得旋轉(zhuǎn)矩陣盈罐,然后通過warpAffine()方法將獲得的矩陣用到對圖片的旋轉(zhuǎn)縮放操作中榜跌。

人臉識別

https://github.com/MoeDisk/OpenCV_Qt_Learn/tree/master/Pic_FaceRecognition_1

123456789101112131415161718192021222324252627282930void MainWindow::imgProc(){? ? CascadeClassifier face_detector;? ? CascadeClassifier eyes_detector;? ? string fDetectorPath="D:/Work/Code/Learn/OpenCV01/Qt/face_recognition/haarcascade_frontalface_alt.xml";? ? face_detector.load(fDetectorPath);? ? string eDetectorPath="D:/Work/Code/Learn/OpenCV01/Qt/face_recognition/haarcascade_eye_tree_eyeglasses.xml";? ? eyes_detector.load(eDetectorPath);? ? vector<Rect> faces;? ? Mat imgSrc=myImg;? ? Mat imgGray;? ? cvtColor(imgSrc,imgGray,CV_RGB2GRAY);? ? equalizeHist(imgGray,imgGray);? ? face_detector.detectMultiScale(imgGray,faces,1.1,2,0|CV_HAAR_SCALE_IMAGE,Size(30,30));? ? for(int i=0;i<faces.size();i++){? ? ? ? Point center(faces[i].x+faces[i].width*0.5,faces[i].y+faces[i].height*0.5);? ? ? ? ellipse(imgSrc,center,Size(faces[i].width*0.5,faces[i].height*0.5),0,0,360,Scalar(255,0,255),4,8,0);? ? ? ? Mat faceROI=imgGray(faces[i]);? ? ? ? vector<Rect> eyes;? ? ? ? eyes_detector.detectMultiScale(faceROI,eyes,1.1,2,0|CV_HAAR_SCALE_IMAGE,Size(30,30));? ? ? ? for(int j=0;j<eyes.size();j++){? ? ? ? ? ? Point center(faces[i].x+eyes[j].x+eyes[j].width*0.5,faces[i].y+eyes[j].y+eyes[j].height*0.5);? ? ? ? ? ? int radius=cvRound((eyes[j].width+eyes[i].height)*0.25);? ? ? ? ? ? circle(imgSrc,center,radius,Scalar(255,0,0),4,8,0);? ? ? ? }? ? }? ? Mat imgDst=imgSrc;? ? myQImg=QImage((const unsigned char*)(imgDst.data),imgDst.cols,imgDst.rows,QImage::Format_RGB888);? ? QMessageBox::about(NULL, " ", "Done");? ? imgShow();}

eyes_detector.load(eDetectorPath);:

load()方法用于加載一個XML分類器文件,OpenCV既支持Haar特征算法也支持LBP特征算法的分類器盅粪。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末钓葫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子票顾,更是在濱河造成了極大的恐慌础浮,老刑警劉巖帆调,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異豆同,居然都是意外死亡番刊,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門影锈,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芹务,“玉大人,你說我怎么就攤上這事鸭廷≡姹В” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵辆床,是天一觀的道長佳晶。 經(jīng)常有香客問我,道長讼载,這世上最難降的妖魔是什么轿秧? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮咨堤,結(jié)果婚禮上淤刃,老公的妹妹穿的比我還像新娘。我一直安慰自己吱型,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布陨仅。 她就那樣靜靜地躺著津滞,像睡著了一般。 火紅的嫁衣襯著肌膚如雪灼伤。 梳的紋絲不亂的頭發(fā)上触徐,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音狐赡,去河邊找鬼撞鹉。 笑死,一個胖子當(dāng)著我的面吹牛颖侄,可吹牛的內(nèi)容都是我干的鸟雏。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼览祖,長吁一口氣:“原來是場噩夢啊……” “哼孝鹊!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起展蒂,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤又活,失蹤者是張志新(化名)和其女友劉穎苔咪,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柳骄,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡团赏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了耐薯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片舔清。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖可柿,靈堂內(nèi)的尸體忽然破棺而出鸠踪,到底是詐尸還是另有隱情,我是刑警寧澤复斥,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布营密,位于F島的核電站,受9級特大地震影響目锭,放射性物質(zhì)發(fā)生泄漏评汰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一痢虹、第九天 我趴在偏房一處隱蔽的房頂上張望被去。 院中可真熱鬧,春花似錦奖唯、人聲如沸惨缆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坯墨。三九已至,卻和暖如春病往,著一層夾襖步出監(jiān)牢的瞬間捣染,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工停巷, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留耍攘,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓畔勤,卻偏偏與公主長得像蕾各,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子硼被,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容