生活随笔
收集整理的這篇文章主要介紹了
使用OpenCV开发机器视觉项目
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
?
每過幾天就去看看OpenCV.org的更新,今天突然發現了一個有趣的東西。http://opencv.org/mastering-opencv-with-practical-computer-vision-projects.html。弄opencv的人出版了一個Mastering OpenCV with Practical Computer Vision Projects的書,也就是用OpenCV開發的一切有意思的項目。
使用OpenCV開發機器視覺項目
?有以下9個章節
Chapters:
Screenshots:
- Ch1) Cartoonifier and Skin Changer for Android:?
- Ch2) Marker-based Augmented Reality on iPhone or iPad:?
- Ch3) Marker-less Augmented Reality:?
- Ch4) Exploring Structure from Motion using OpenCV:?
- Ch5) Number Plate Recognition using SVM and Neural Networks:?
- Ch6) Non-rigid Face Tracking:?
- Ch7) 3D Head Pose Estimation using AAM and POSIT:?
- Ch8) Face Recognition using Eigenfaces or Fisherfaces:?
- Ch9) Developing Fluid Wall using the Microsoft Kinect:?
? ? ?看看,他們確實涵蓋了當今最熱門的一些機器視覺相關項目,其中包括我喜歡的Kinect,甚至我熟悉的人臉識別、人臉跟蹤、人臉朝向估計等等(這么多關于人臉的!),還包括虛擬現實之類技術,有時間也得看看。這本書可以買紙質版也可以買電子版,購買地址?PacktPub。好吧,估計一般人是買不到的,國外的書果然不便宜,$44.99
? ? ?不過書中配套的項目源碼倒是都有的!https://github.com/MasteringOpenCV/code
? ? ?
第一個項目:卡通畫和膚色變化初探
我在windows上嘗試編譯了第一個例子(他既有Android平臺的代碼也給出了PC平臺的)。以下是截圖:
? ? 第一張和第四張圖片都是卡通圖,第2張是evil狀態的,所以有點慘不忍睹吧,第三張是素描。具體算法我還未去細讀,給出下載第一個項目的VS2010地址。通過debug可以編譯出可用的exe,而release盡然無法檢測到攝像頭以致exe無法運行,編譯時注意。
? ?給出主要的卡通畫函數實現代碼:
[cpp] view plaincopy
??????????????#include?"cartoon.h"??#include?"ImageUtils.h"?//?Handy?functions?for?debugging?OpenCV?images,?by?Shervin?Emami.??????????????????void?cartoonifyImage(Mat?srcColor,?Mat?dst,?bool?sketchMode,?bool?alienMode,?bool?evilMode,?int?debugType)??{????????????Mat?srcGray;??????cvtColor(srcColor,?srcGray,?CV_BGR2GRAY);??????????????medianBlur(srcGray,?srcGray,?7);????????Size?size?=?srcColor.size();??????Mat?mask?=?Mat(size,?CV_8U);??????Mat?edges?=?Mat(size,?CV_8U);??????if?(!evilMode)?{????????????????????Laplacian(srcGray,?edges,?CV_8U,?5);??????????threshold(edges,?mask,?80,?255,?THRESH_BINARY_INV);??????????????????????????????removePepperNoise(mask);??????}??????else?{??????????????????????????????Mat?edges2;??????????Scharr(srcGray,?edges,?CV_8U,?1,?0);??????????Scharr(srcGray,?edges2,?CV_8U,?1,?0,?-1);??????????edges?+=?edges2;??????????threshold(edges,?mask,?12,?255,?THRESH_BINARY_INV);??????????medianBlur(mask,?mask,?3);??????}??????????????????????????if?(sketchMode)?{????????????????????cvtColor(mask,?dst,?CV_GRAY2BGR);??????????return;??????}????????????????????Size?smallSize;??????smallSize.width?=?size.width/2;??????smallSize.height?=?size.height/2;??????Mat?smallImg?=?Mat(smallSize,?CV_8UC3);??????resize(srcColor,?smallImg,?smallSize,?0,0,?INTER_LINEAR);????????????????????Mat?tmp?=?Mat(smallSize,?CV_8UC3);??????int?repetitions?=?7;??????????????for?(int?i=0;?i<repetitions;?i++)?{??????????int?size?=?9;?????????????????????double?sigmaColor?=?9;????????????double?sigmaSpace?=?7;????????????bilateralFilter(smallImg,?tmp,?size,?sigmaColor,?sigmaSpace);??????????bilateralFilter(tmp,?smallImg,?size,?sigmaColor,?sigmaSpace);??????}????????if?(alienMode)?{??????????????????????????????changeFacialSkinColor(smallImg,?edges,?debugType);??????}??????????????resize(smallImg,?srcColor,?size,?0,0,?INTER_LINEAR);??????????????memset((char*)dst.data,?0,?dst.step?*?dst.rows);??????????????srcColor.copyTo(dst,?mask);??}????????????void?changeFacialSkinColor(Mat?smallImgBGR,?Mat?bigEdges,?int?debugType)??{????????????????????Mat?yuv?=?Mat(smallImgBGR.size(),?CV_8UC3);??????????cvtColor(smallImgBGR,?yuv,?CV_BGR2YCrCb);??????????????????????????????????????????int?sw?=?smallImgBGR.cols;??????????int?sh?=?smallImgBGR.rows;??????????Mat?maskPlusBorder?=?Mat::zeros(sh+2,?sw+2,?CV_8U);??????????Mat?mask?=?maskPlusBorder(Rect(1,1,sw,sh));????????????resize(bigEdges,?mask,?smallImgBGR.size());??????????????????????threshold(mask,?mask,?80,?255,?THRESH_BINARY);????????????????????dilate(mask,?mask,?Mat());??????????erode(mask,?mask,?Mat());????????????????????????????????????????????????????int?const?NUM_SKIN_POINTS?=?6;??????????Point?skinPts[NUM_SKIN_POINTS];??????????skinPts[0]?=?Point(sw/2,??????????sh/2?-?sh/6);??????????skinPts[1]?=?Point(sw/2?-?sw/11,??sh/2?-?sh/6);??????????skinPts[2]?=?Point(sw/2?+?sw/11,??sh/2?-?sh/6);??????????skinPts[3]?=?Point(sw/2,??????????sh/2?+?sh/16);??????????skinPts[4]?=?Point(sw/2?-?sw/9,???sh/2?+?sh/16);??????????skinPts[5]?=?Point(sw/2?+?sw/9,???sh/2?+?sh/16);??????????????????????????????const?int?LOWER_Y?=?60;??????????const?int?UPPER_Y?=?80;??????????const?int?LOWER_Cr?=?25;??????????const?int?UPPER_Cr?=?15;??????????const?int?LOWER_Cb?=?20;??????????const?int?UPPER_Cb?=?15;??????????Scalar?lowerDiff?=?Scalar(LOWER_Y,?LOWER_Cr,?LOWER_Cb);??????????Scalar?upperDiff?=?Scalar(UPPER_Y,?UPPER_Cr,?UPPER_Cb);??????????????????????????????Mat?edgeMask?=?mask.clone();??????????????for?(int?i=0;?i<NUM_SKIN_POINTS;?i++)?{????????????????????????????const?int?flags?=?4?|?FLOODFILL_FIXED_RANGE?|?FLOODFILL_MASK_ONLY;??????????????floodFill(yuv,?maskPlusBorder,?skinPts[i],?Scalar(),?NULL,?lowerDiff,?upperDiff,?flags);??????????????if?(debugType?>=?1)??????????????????circle(smallImgBGR,?skinPts[i],?5,?CV_RGB(0,?0,?255),?1,?CV_AA);??????????}??????????if?(debugType?>=?2)??????????????imshow("flood?mask",?mask*120);?????????????????????????????????mask?-=?edgeMask;????????????????????????????????int?Red?=?0;??????????int?Green?=?70;??????????int?Blue?=?0;??????????add(smallImgBGR,?Scalar(Blue,?Green,?Red),?smallImgBGR,?mask);??}????????????void?removePepperNoise(Mat?&mask)??{????????????for?(int?y=2;?y<mask.rows-2;?y++)?{????????????????????uchar?*pThis?=?mask.ptr(y);??????????uchar?*pUp1?=?mask.ptr(y-1);??????????uchar?*pUp2?=?mask.ptr(y-2);??????????uchar?*pDown1?=?mask.ptr(y+1);??????????uchar?*pDown2?=?mask.ptr(y+2);??????????????????????pThis?+=?2;??????????pUp1?+=?2;??????????pUp2?+=?2;??????????pDown1?+=?2;??????????pDown2?+=?2;??????????for?(int?x=2;?x<mask.cols-2;?x++)?{??????????????uchar?v?=?*pThis;?????????????????????????????????????????????if?(v?==?0)?{??????????????????bool?allAbove?=?*(pUp2?-?2)?&&?*(pUp2?-?1)?&&?*(pUp2)?&&?*(pUp2?+?1)?&&?*(pUp2?+?2);??????????????????bool?allLeft?=?*(pUp1?-?2)?&&?*(pThis?-?2)?&&?*(pDown1?-?2);??????????????????bool?allBelow?=?*(pDown2?-?2)?&&?*(pDown2?-?1)?&&?*(pDown2)?&&?*(pDown2?+?1)?&&?*(pDown2?+?2);??????????????????bool?allRight?=?*(pUp1?+?2)?&&?*(pThis?+?2)?&&?*(pDown1?+?2);??????????????????bool?surroundings?=?allAbove?&&?allLeft?&&?allBelow?&&?allRight;??????????????????if?(surroundings?==?true)?{??????????????????????????????????????????????????????????????????*(pUp1?-?1)?=?255;??????????????????????*(pUp1?+?0)?=?255;??????????????????????*(pUp1?+?1)?=?255;??????????????????????*(pThis?-?1)?=?255;??????????????????????*(pThis?+?0)?=?255;??????????????????????*(pThis?+?1)?=?255;??????????????????????*(pDown1?-?1)?=?255;??????????????????????*(pDown1?+?0)?=?255;??????????????????????*(pDown1?+?1)?=?255;??????????????????}??????????????????????????????????????????????????????pThis?+=?2;??????????????????pUp1?+=?2;??????????????????pUp2?+=?2;??????????????????pDown1?+=?2;??????????????????pDown2?+=?2;??????????????}????????????????????????????pThis++;??????????????pUp1++;??????????????pUp2++;??????????????pDown1++;??????????????pDown2++;??????????}??????}??}????????????void?drawFaceStickFigure(Mat?dst)??{??????Size?size?=?dst.size();??????int?sw?=?size.width;??????int?sh?=?size.height;??????????????Mat?faceOutline?=?Mat::zeros(size,?CV_8UC3);??????Scalar?color?=?CV_RGB(255,255,0);?????????int?thickness?=?4;????????????int?faceH?=?sh/2?*?70/100;??????????????int?faceW?=?faceH?*?72/100;?????????????ellipse(faceOutline,?Point(sw/2,?sh/2),?Size(faceW,?faceH),?0,?0,?360,?color,?thickness,?CV_AA);????????????int?eyeW?=?faceW?*?23/100;??????int?eyeH?=?faceH?*?11/100;??????int?eyeX?=?faceW?*?48/100;??????int?eyeY?=?faceH?*?13/100;????????????int?eyeA?=?15;???????int?eyeYshift?=?11;????????????ellipse(faceOutline,?Point(sw/2?-?eyeX,?sh/2?-?eyeY),?Size(eyeW,?eyeH),?0,?180+eyeA,?360-eyeA,?color,?thickness,?CV_AA);????????????ellipse(faceOutline,?Point(sw/2?-?eyeX,?sh/2?-?eyeY?-?eyeYshift),?Size(eyeW,?eyeH),?0,?0+eyeA,?180-eyeA,?color,?thickness,?CV_AA);????????????ellipse(faceOutline,?Point(sw/2?+?eyeX,?sh/2?-?eyeY),?Size(eyeW,?eyeH),?0,?180+eyeA,?360-eyeA,?color,?thickness,?CV_AA);????????????ellipse(faceOutline,?Point(sw/2?+?eyeX,?sh/2?-?eyeY?-?eyeYshift),?Size(eyeW,?eyeH),?0,?0+eyeA,?180-eyeA,?color,?thickness,?CV_AA);??????????????int?mouthY?=?faceH?*?53/100;??????int?mouthW?=?faceW?*?45/100;??????int?mouthH?=?faceH?*?6/100;??????ellipse(faceOutline,?Point(sw/2,?sh/2?+?mouthY),?Size(mouthW,?mouthH),?0,?0,?180,?color,?thickness,?CV_AA);??????????????int?fontFace?=?FONT_HERSHEY_COMPLEX;??????float?fontScale?=?1.0f;??????int?fontThickness?=?2;??????putText(faceOutline,?"Put?your?face?here",?Point(sw?*?23/100,?sh?*?10/100),?fontFace,?fontScale,?color,?fontThickness,?CV_AA);????????????????????addWeighted(dst,?1.0,?faceOutline,?0.7,?0,?dst,?CV_8UC3);??}?
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀
總結
以上是生活随笔為你收集整理的使用OpenCV开发机器视觉项目的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。