Professional Documents
Culture Documents
OpenCVshapedetectionPyImageSearch
Navigation
OpenCVshapedetection
byAdrianRosebrockonFebruary8,2016inImageProcessing,OpenCV3,Tutorials
Like
16
52
Thistutorialisthesecondpostinourthreepartseriesonshapedetectionandanalysis.
LastweekwelearnedhowtocomputethecenterofacontourusingOpenCV.
Today,wearegoingtoleveragecontourpropertiestoactuallylabelandidentifyshapesinanimage,just
likeinthefigureatthetopofthispost.
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
1/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Lookingforthesourcecodetothispost?
Jumprighttothedownloadssection.
OpenCVshapedetection
Beforewegetstartedwiththistutorial,letsquicklyreviewourprojectstructure:
OpenCV shape detection
1 |--- pyimagesearch
2 ||--- __init__.py
3 ||--- shapedetector.py
4 |--- detect_shapes.py
5 |--- shapes_and_colors.png
Shell
Shell
Definingourshapedetector
Thefirststepinbuildingourshapedetectoristowritesomecodetoencapsulatetheshapeidentification
logic.
Letsgoaheadanddefineour
followingcode:
ShapeDetector
.Openupthe
shapedetector.py
fileandinsertthe
shapedetector.py
1 # import the necessary packages
2 import cv2
3
4 class ShapeDetector:
5
def __init__(self):
6
pass
7
8
def detect(self, c):
9
# initialize the shape name and approximate the contour
10
shape = "unidentified"
11
peri = cv2.arcLength(c, True)
12
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
Line4startsthedefinitionofour
nothingneedstobeinitialized.
ShapeDetector
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
class.Wellskipthe
__init__
Python
constructorheresince
2/17
6/21/2016
OpenCVshapedetectionPyImageSearch
,thecontour(i.e.,
Inordertoperformshapedetection,wellbeusingcontourapproximation.
Asthenamesuggests,contourapproximationisanalgorithmforreducingthenumberofpointsinacurve
withareducedsetofpointsthusthetermapproximation.
ThisalgorithmiscommonlyknownastheRamerDouglasPeuckeralgorithm,orsimplythesplitand
mergealgorithm.
Contourapproximationispredicatedontheassumptionthatacurvecanbeapproximatedbyaseriesof
shortlinesegments.Thisleadstoaresultingapproximatedcurvethatconsistsofasubsetofpointsthat
weredefinedbytheoriginalcruve.
ContourapproximationisactuallyalreadyimplementedinOpenCVviathe
cv2.approxPolyDP
method.
Inordertoperformcontourapproximation,wefirstcomputetheperimeterofthecontour(Line11),followed
byconstructingtheactualcontourapproximation(Line12).
Commonvaluesforthesecondparameterto
originalcontourperimeter.
cv2.approxPolyDP
arenormallyintherangeof15%ofthe
Note:Interestedinamoreindepthlookatcontourapproximation?Besuretocheckoutthe
PyImageSearchGuruscoursewhereIdiscusscomputervisionandimageprocessingfundamentalssuch
ascontoursandconnectedcomponentanalysisindetail.
Givenourapproximatedcontour,wecanmoveontoperformingshapedetection:
OpenCV shape detection
14
# if the shape is a triangle, it will have 3 vertices
15
if len(approx) == 3:
16
shape = "triangle"
17
18
# if the shape has 4 vertices, it is either a square or
19
# a rectangle
20
elif len(approx) == 4:
21
# compute the bounding box of the contour and use the
22
# bounding box to compute the aspect ratio
23
(x, y, w, h) = cv2.boundingRect(approx)
24
ar = w / float(h)
25
26
# a square will have an aspect ratio that is approximately
27
# equal to one, otherwise, the shape is a rectangle
28
shape = "square" if ar >= 0.95 and ar <= 1.05 else "rectangle"
29
30
# if the shape is a pentagon, it will have 5 vertices
31
elif len(approx) == 5:
32
shape = "pentagon"
33
34
# otherwise, we assume the shape is a circle
35
else:
36
shape = "circle"
37
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
Python
3/17
6/21/2016
38
39
OpenCVshapedetectionPyImageSearch
Itsimportanttounderstandthatacontourconsistsofalistofvertices.Wecancheckthenumberof
entriesinthislisttodeterminetheshapeofanobject.
Forexample,iftheapproximatedcontourhasthreevertices,thenitmustbeatriangle(Lines15and16).
Ifacontourhasfourvertices,thenitmustbeeitherasquareorarectangle(Line20).Todeterminewhich,
wecomputetheaspectratiooftheshape,whichissimplythewidthofthecontourboundingboxdividedby
theheight(Lines23and24).Iftheaspectratiois~1.0,thenweareexaminingasquare(sinceallsides
haveapproximatelyequallength).Otherwise,theshapeisarectangle.
Ifacontourhasfivevertices,wecanlabelitasapentagon(Line31and32).
Otherwise,byprocessofelimination(incontextofthisexample,ofcourse),wecanmaketheassumption
thattheshapeweareexaminingisacircle(Lines35and36).
Finally,wereturntheidentifiedshapetothecallingmethod.
ShapedetectionwithOpenCV
Nowthatour
ShapeDetector
classhasbeendefined,letscreatethe
detect_shapes.py
driverscript:
Free21daycrashcourse
oncomputervision&
imagesearchengines
Python
Interestedincomputervisionandimagesearch
WestartoffonLines25byimportingourrequiredpackages.Noticehowwereimportingour
engines,butdon'tknowwheretostart?Letme
implementationofthe ShapeDetector classfromthe shapedetector
submoduleof pyimagesearch .
help.I'vecreatedafree,21daycrashcoursethat
ishandtailoredtogiveyouthebestpossible
Lines811handleparsingourcommandlinearguments.Weonlyneedasingleswitchhere,
--image ,
introductiontocomputervision.Soundgood?Enter
whichisthepathtowheretheimagewewanttoprocessresidesondisk.
youremailbelowtostartyourjourneytobecoming
Nextup,letspreprocessourimage:
acomputervisionmaster.
EmailAddress
Python
4/17
6/21/2016
21
22
23
24
25
26
27
28
29
30
OpenCVshapedetectionPyImageSearch
First,weloadourimagefromdiskonLine15andresizeitonLine16.Wethenkeeptrackofthe ratio
oftheoldheighttothenewresizedheightonLine17wellfindoutexactlywhywedothislaterinthe
tutorial.
Fromthere,Lines2123handleconvertingtheresizedimagetograyscale,smoothingittoreducehigh
frequencynoise,andfinallythresholdingittorevealtheshapesintheimage.
Afterthresholding,ourimageshouldlooklikethis:
Free21daycrashcourseoncomputer
vision&imagesearchengines
Free21daycrashcourse
oncomputervision&
imagesearchengines
Interestedincomputervisionandimagesearch
engines,butdon'tknowwheretostart?Letme
help.I'vecreatedafree,21daycrashcoursethat
ishandtailoredtogiveyouthebestpossible
introductiontocomputervision.Soundgood?Enter
Figure1:Thresholdingrevealstheshapesinourimage.
youremailbelowtostartyourjourneytobecoming
acomputervisionmaster.
Noticehowourimagehasbeenbinarizedtheshapesappearasawhiteforegroundagainstablack
background.
EmailAddress
Lastly,wefindcontoursinourbinaryimage,handlegrabbingthecorrecttuplevaluefrom
LET'SDOIT!
cv2.findContours basedonourOpenCVversion,andfinallyinitializeour ShapeDetector (Lines2730).
Thelaststepistoidentifyeachofthecontours:
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
5/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Python
OnLine33westartloopingovereachoftheindividualcontours.Foreachofthem,wecomputethecenter
ofthecontour,followedbyperformingshapedetectionandlabeling.
Sinceweareprocessingthecontoursextractedfromtheresizedimage(ratherthantheoriginalimage),we
needtomultiplythecontoursandcenter(x,y)coordinatesbyourresize ratio (Lines4345).Thiswill
giveusthecorrect(x,y)coordinatesforboththecontoursandcentroidoftheoriginalimage.
Lastly,wedrawthecontoursandthelabeledshapeonourimage(Lines4448),followedbydisplayingour
results(Lines51and52).
Toseeourshapedetectorinaction,justexecutethefollowingcommand:
OpenCV shape detection
1 $ python detect_shapes.py --image shapes_and_colors.png
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
Shell
6/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Figure2:PerformingshapedetectionwithOpenCV.
Asyoucanseefromtheanimationabove,ourscriptloopsovereachoftheshapesindividually,performs
shapedetectiononeachone,andthendrawsthenameoftheshapeontheobject.
Summary
Intodayspostblog,welearnedhowtoperformshapedetectionwithOpenCVandPython.
Toaccomplishthis,weleveragedcontourapproximation,theprocessofreducingthenumberofpointsona
curvetoamoresimpleapproximatedversion.
Then,basedonthiscontourapproximation,weexaminedthenumberofverticeseachshapehas.Given
thevertexcount,wewereabletoaccuratelylabeleachoftheshapes.
Thislessonispartofathreepartseriesonshapedetectionandanalysis.Lastweekwecoveredhowto
computethecenterofacontour.TodaywecoveredshapedetectionwithOpenCV.Andnextweekwell
discusshowtolabeltheactualcolorofashapeusingcolorchannelstatistics.
Besuretoenteryouremailaddressintheformbelowtobenotifiedwhenthenextpostgoesliveyou
wontwanttomissit!
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
7/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Downloads:
Ifyouwouldliketodownloadthecodeandimagesusedinthispost,pleaseenteryour
emailaddressintheformbelow.Notonlywillyougeta.zipofthecode,Illalsosend
youaFREE11pageResourceGuideonComputerVisionandImageSearch
Engines,includingexclusivetechniquesthatIdontpostonthisblog!Soundgood?If
so,enteryouremailaddressandIllsendyouthecodeimmediately!
Emailaddress:
Youremailaddress
DOWNLOADTHECODE!
ResourceGuide(itstotallyfree).
Enteryouremailaddressbelowtogetmyfree11pageImageSearch
EngineResourceGuidePDF.UncoverexclusivetechniquesthatIdon't
publishonthisblogandstartbuildingimagesearchenginesofyourown!
Youremailaddress
DOWNLOADTHEGUIDE!
approximatecontours,contourproperties,contours,findcontours,shapes
OpenCVcenterofcontour
DeterminingobjectcolorwithOpenCV
27ResponsestoOpenCVshapedetection
leenaFebruary9,2016at5:59am#
REPLY
Whyitisscanningandlabelingfrombottomtotop?
Howtotoscanandlabeltoptobottom?
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
8/17
6/21/2016
OpenCVshapedetectionPyImageSearch
AdrianRosebrockFebruary9,2016at3:54pm#
REPLY
Thatishowthecv2.findContoursmethodisimplemented.Ifyouwouldliketosort
contours,seethispost.
leenaFebruary17,2016at4:57am#
REPLY
ThanksAdrian.ItworkedandIamabletoscanfromtoptobottom.
Pleasehelpmeinidentifyinglinesconnectedwithtwoshapeslikeinaflowchart,2boxesare
connectedwithline/arrow
withregards.
leenaFebruary9,2016at6:11am#
REPLY
Ihavedonethesamewith
shapefactor=area/(peri*peri)
ifshapefactor>=0.06andshapefactor=0.0484andshapefactor=0.050andshapefactor=0.032and
shapefactor=0.95andar<=1.05else"rectangle"
AdrianRosebrockFebruary9,2016at3:55pm#
REPLY
Isthereaparticularreasonyouaretakingtheratiooftheareatotheperimetersquared?
Itseemstomaketherulemorecomplicated.
leenaFebruary10,2016at11:11pm#
REPLY
ActuallyIdonotknowthereason,justitgotsolvedmyproblem,soItookit.Youor
somebodycanhelpmeunderstandingthisandthebettersolution.
Thanks
VincentFebruary18,2016at3:41pm#
REPLY
HiAdrian,
Firstandforemost,thankyouforthisexcellenttutorial.Veryusefulandinformative.
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
9/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Ihaveusedthelogicheretodetectredtrianglesinawebcamfeed.Ihavealsotweakedthe
shapedetectorclasstoidentifyonlytriangles.Iamabletosuccessfullyidentifyaredtriangle.
http://imgur.com/6Z9CnBA
Ivenoticedthatsometimesaverymessycontourwillbeclassifiedincorrectlyasatriangle.
http://imgur.com/4a06psM
Whatwouldbeagoodwaytotweakthis?
http://pastie.org/10727912
http://pastie.org/10727915
AdrianRosebrockFebruary18,2016at4:05pm#
REPLY
Keepinmindthatthecodeisonlyasgoodastheimagesthatyouputintoit.Thecode
detailedinthispostassumessimpleshapesthatcanberecognizedutilizingcontourproperties.For
moreadvancedshapes,orshapesthathavesubstantialvariancesinhowtheyappear(suchas
noisycontours),youmightneedtotrainyourowncustomobjectdetector.
Anyway,thereasonsometimesevenmessycontoursgetclassifieddifferentlyisduetothecontour
approximation.Playaroundwiththepercentageusedincv2.approxPolyDPandyoullbeableto
seethedifferences.
PengMarch4,2016at7:49pm#
REPLY
HiAdrian,
Thankyouformakingthis.Alittlefeedbackontheimagefile.
Inoticethatifusinga.jpgfileasthesource,themoment(cnt)willnotgetacorrectvalue.
Itreportanerror:
cntX=int(M[m10]/M[m00])
ZeroDivisionError:floatdivisionbyzero
Anyideasonthis?
Thanks
AdrianRosebrockMarch6,2016at9:20am#
REPLY
VersionversionofOpenCVandPythonareyouusing?
Ineithercase,youcanresolvetheissuebydoing:
1 if M["m00"] > 0:
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
10/17
6/21/2016
OpenCVshapedetectionPyImageSearch
Thisifstatementwilltakecareofthedividebyzeroerror.
Alternatively,youcanaddatinyvaluetothemomenttoensurethereisnodividebyzeroproblem:
cX=(M["c10"]/(M["m00"]+1e7))
EuanMarch10,2016at10:00pm#
REPLY
HiAdrian,
Firstlythanksforagreattutorialandsite.ImamechanicalengineerandnoobtoopenCV,pythonand
linuxandhavemanagedtogetopenCV3.0andpython2.7setupthankstoyourtutorialhere.
http://www.pyimagesearch.com/2015/06/22/installopencv30andpython27onubuntu/
Inordertogetthiscoderunningonmysetup,Ineededtomodifyfloatonline17tointasitwas
causingcastproblemsonline43c*=ratio.Ibelievethisisprobablyduetoanupdateofhowpython
worksfromhowitworkedwhenyouwrotethistutorial.Isthisthecase?
AdrianRosebrockMarch13,2016at10:29am#
REPLY
Interesting,Brandonmentionedthisissueinacommentabove.WhichversionofOpenCV
andNumPyareyouusing?
brandonMarch11,2016at4:20pm#
REPLY
Adrian,greatstuff.Ivelearnedalotfromyourblog,andplanonpurchasingthebooksoon.I
wasworkingthroughthispostfornow,andImgettingthefollowingtracebackerror:
AdrianRosebrockMarch13,2016at10:21am#
REPLY
Ipersonallyhaventseenthiserrormessagebefore.CanyouletmeknowwhichOpenCV
andNumPyversionsyouareusing?
BrandonMarch14,2016at12:28pm#
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
REPLY
11/17
6/21/2016
OpenCVshapedetectionPyImageSearch
numpyis1.10.4,andithappenswithbothOpenCV2.4.12and3.1.0(inavirtualenv,
thankstoanotherofyourtutorials)underPython2.7onOSX10.11.3
Theworkaroundwassimplytoadjustdatatypespreandpostmultiplication:
c=c.astype(np.float_)
c*=ratio
c=c.astype(np.int32)
Itworksnow.
AdrianRosebrockMarch14,2016at3:15pm#
REPLY
ThanksforthetipBrandon!Illbesuretodiveintothismore.ImusingNumPy
1.9.3,soperhapsthisisanissuewithNumPy1.10.X.
AhmedAbdeldaimMarch24,2016at10:30am#
REPLY
GreatworkMr.Adrian
butisthereawaytomaketheselectionmoresofter,forexamplebyreducepointsize??
orthisisthebestresult??
AdrianRosebrockMarch24,2016at5:10pm#
REPLY
Absolutely,youjustneedtoapplycontourapproximationfirst.Idetailcontour
approximationinafewblogposts,butIwouldstartwiththisone.
AhmedAbdeldaimMarch26,2016at4:05pm#
REPLY
Thanksforyourhelp.
darshanMarch26,2016at2:09am#
REPLY
howtoinstallimutilsmodule
IusedpipinstallimutilsImgettingerror
AdrianRosebrockMarch27,2016at9:14am#
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
REPLY
12/17
6/21/2016
OpenCVshapedetectionPyImageSearch
PleaseseetheOpenCVshapedetectionsectionofthisblogpost.Youjustneedtouse
pip
$pipinstallimutils
firozkhanApril23,2016at10:42am#
REPLY
hiadrianitisonlydetctingonepentagonandnothingelse
AdrianRosebrockApril25,2016at2:09pm#
REPLY
Makesureyouclickonthewindowandpressanykeyonyourkeyboardthiswill
advancethescript.Rightnowakeypressisrequiredaftereachdetection.
DiegoFernandoBarriosApril29,2016at5:08pm#
REPLY
Goodafthernoon!
Thanksverymuchforthistutotrial,youredoingagreatandutilwork.
Friend,Ihaveaproblemwithcontourdetection,whenIchangetheimage,theprojectdontwork(Im
usingablackbackground,ItaketheimagefromUSBcamera).Inothaveproblemwiththeimagepath.
Thepythonscriptsshouldrecognize(9ninerectangles)butjustoneisrecognized
Sorryforthewriting,myenglishisnotsogood.
Iwouldlikethatyoucanhelpme.Imworkinginmyworkgrade.
Thanksverymuch!
AdrianRosebrockApril30,2016at3:55pm#
REPLY
Dependingonyourimage,thiscouldbeanissuewithsegmentationand/orthecontours.
Makesurethatafterthresholdingyour9rectangleshavebeenclearlysegmented.Fromthere,
moveontothecontourapproximationandseehowmanypointsarereturnedbythe
approximation.Youmightneedtotweakthecv2.approxPolyDPparameters.
itaiMay8,2016at4:24am#
REPLY
HeyAdrian,
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
13/17
6/21/2016
OpenCVshapedetectionPyImageSearch
IwaswonderingwhydidyouusetheRamerDouglasPeuckeralgorithmtoreducethesetofpoints,
insteadofusingtheconvexhull?
Thanks
AdrianRosebrockMay8,2016at8:12am#
REPLY
ThecontourapproximationalgorithmandConvexHullalgorithmareusedfortwoseparate
purposes.Asthenameimplies,contourapproximationisusedtoreducethenumberofpoints
alongacontourbysimplifyingthecontourbasedonapercentageoftheperimeter.Yourresulting
contourapproximationisthisasimplificationoftheshapebyutilizingpointsthatarealreadypartof
theshape.
Theconvexhullontheotherhandisthesmallestconvexsetthatcontainsallpointsalongthe
contouritis,bydefinition,notasimplificationofthecontourshapeandtheresultingconvexhull
actuallycontainspointsthatarenotpartoftheoriginalshape.
Inthiscase,IusedcontourapproximationbecauseIwantedtoreducethenumberof(x,y)
coordinatesthatcomprisethecontour,whileensuringthatallpointsintheresultingapproximation
werealsopartoftheoriginalshape.
LeaveaReply
Name(required)
Email(willnotbepublished)(required)
Website
SUBMITCOMMENT
ResourceGuide(itstotallyfree).
Clickthebuttonbelowtogetmyfree11pageImageSearchEngineResourceGuidePDF.Uncoverexclusive
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
14/17
6/21/2016
OpenCVshapedetectionPyImageSearch
techniquesthatIdon'tpublishonthisblogandstartbuildingimagesearchenginesofyourown.
DownloadforFree!
Youcandetectfacesinimages&video.
Areyouinterestedindetectingfacesinimages&video?ButtiredofGooglingfortutorialsthatneverwork?Then
letmehelp!Iguaranteethatmynewbookwillturnyouintoafacedetectionninjabytheendofthisweekend.Click
heretogiveitashotyourself.
CLICKHERETOMASTERFACEDETECTION
PyImageSearchGurus:NOWENROLLING!
ThePyImageSearchGuruscourseisnowenrolling!Insidethecourseyou'lllearnhowtoperform:
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
15/17
6/21/2016
OpenCVshapedetectionPyImageSearch
AutomaticLicensePlateRecognition(ANPR)
DeepLearning
FaceRecognition
andmuchmore!
Clickthebuttonbelowtolearnmoreaboutthecourse,takeatour,andget10(FREE)samplelessons.
TAKEATOUR&GET10(FREE)LESSONS
Hello!ImAdrianRosebrock.
I'manentrepreneurandPh.Dwhohaslaunchedtwosuccessfulimagesearchengines,IDMyPill
andChicEngine.I'mheretosharemytips,tricks,andhacksI'velearnedalongtheway.
Learncomputervisioninasingleweekend.
Wanttolearncomputervision&OpenCV?Icanteachyouinasingleweekend.Iknow.Itsoundscrazy,butitsno
joke.Mynewbookisyourguaranteed,quickstartguidetobecominganOpenCVNinja.Sowhynotgiveitatry?
Clickheretobecomeacomputervisionninja.
CLICKHERETOBECOMEANOPENCVNINJA
SubscribeviaRSS
Nevermissapost!SubscribetothePyImageSearchRSSFeedandkeepuptodatewithmyimage
searchenginetutorials,tips,andtricks
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
16/17
6/21/2016
OpenCVshapedetectionPyImageSearch
POPULAR
InstallOpenCVandPythononyourRaspberryPi2andB+
FEBRUARY23,2015
HomesurveillanceandmotiondetectionwiththeRaspberryPi,Python,OpenCV,andDropbox
JUNE1,2015
HowtoinstallOpenCV3onRaspbianJessie
OCTOBER26,2015
InstallOpenCV3.0andPython2.7+onUbuntu
JUNE22,2015
InstallOpenCV3.0andPython2.7+onOSX
JUNE15,2015
BasicmotiondetectionandtrackingwithPythonandOpenCV
MAY25,2015
InstallingOpenCV3.0forbothPython2.7andPython3+onyourRaspberryPi2
JULY27,2015
Search
Search...
FindmeonTwitter,Facebook,Google+,andLinkedIn.
2016PyImageSearch.AllRightsReserved.
http://www.pyimagesearch.com/2016/02/08/opencvshapedetection/
17/17