You are on page 1of 5

18/10/2015 c++HowtodetectimagegradientornormalusingOpenCVStackOverflow

signup login tour help stackoverflowcareers

StackOverflowisaquestionandanswersiteforprofessionalandenthusiastprogrammers.It's100%free. Signup

HowtodetectimagegradientornormalusingOpenCV

Iwantedtodetectellipseinanimage.SinceIwaslearningMathematicaatthattime,Iaskedaquestionhereandgotasatisfactoryresult
fromtheanswerbelow,whichusedtheRANSACalgorithmtodetectellipse.

However,recentlyIneedtoportittoOpenCV,buttherearesomefunctionsthatonlyexistinMathematica.Oneofthekeyfunctionisthe
"GradientOrientationFilter"function.

Sincetherearefiveparametersforageneralellipse,Ineedtosamplefivepointstodetermineone.Howevere,themoresamplingpoints
indicatesthelowerchancetohaveagoodguess,whichleadstothelowersuccessrateinellipsedetection.Therefore,theanswerfrom
Mathematicaaddanothercondition,thatisthegradientoftheimagemustbeparalleltothegradientoftheellipseequation.Anyway,we'll
onlyneedthreepointstodetermineoneellipseusingleastsquarefromtheMathematicaapproach.Theresultisquitegood.

However,whenItrytofindtheimagegradientusingSobelorScharroperatorinOpenCV,itisnotgoodenough,whichalwaysleadstothe
badresult.

Howtocalculatethegradientorthetangentofanimageaccurately?Thanks!

Resultwithgradient,threepoints

http://stackoverflow.com/questions/22804875/howtodetectimagegradientornormalusingopencv 1/5
18/10/2015 c++HowtodetectimagegradientornormalusingOpenCVStackOverflow

Resultwithoutgradient,fivepoints

updated

Ididsomeedgedetectandmedianblurbeforehandanddrawtheresultontheedgeimage.Myoriginaltestimageislikethis:

Ingeneral,myfinalgoalistodetecttheellipseinasceneoronanobject.Somethinglikethis:

That'swhyIchoosetouseRANSACtofittheellipsefromedgepoints.

c++ opencv ellipse

editedApr2'14at17:44 askedApr2'14at7:53
AlbertK
21 1 9

"Sincetherearefiveparametersforageneralellipse,Ineedtosamplefivepointstodetermineone.">I
wouldbeinterestedtohaveadetailedexplanationonthis,becauseforme3twodimensionalpointsare
enoughtoestimate5scalarparameters.Aboutyourquestion,canyouincludeinyourquestionthecode
http://stackoverflow.com/questions/22804875/howtodetectimagegradientornormalusingopencv 2/5
18/10/2015 c++HowtodetectimagegradientornormalusingOpenCVStackOverflow
youusedtoestimatethegradient?AldurDiscipleApr2'14at9:24

Myideaisthatageneralellipsewouldbeax^2+by^2+cxy+dx+ey+1=0.SoifIwanttosolvethisequation,I
needtohavefivepoint,(x1,y1)~(x5,y5).Substitutethemintothe(x,y)oftheellipseequation,Icansolve
thesimultaneousequationsoffivevariables.That'swhyIsayIneedtosamplefivepointstodetermine
one. AlbertK Apr2'14at17:27

Thecodesnippetishere AlbertK Apr2'14at17:27

Consideringtheupdatedimage,usethegeneralizedHoughtransform.MSalters Apr2'14at22:43

3Answers

You'reusingtermsinanunusualway.

Normallyforimages,theterm"gradient"isinterpretedasiftheimageisamathematicalfunction
f(x,y) .Thisgivesusa (df/dx,df/dy) vectorineachpoint.

Yetyou'relookingattheimageasifit'safunction y=f(x) andthegradientwouldbe f(x)/dx .

Now,ifyoulookatyourimage,you'llseethatthetwointerpretationsaredefinitelyrelated.Your
ellipseisdrawnasasetofcontrastingpixels,andasaresulttherearetwosharpgradientsinthe
imagetheinnerandouter.Theseofcoursecorrespondtothetwonormalvectors,andtherefore
areinoppositedirections.

Alsonotethatyourimagehaspixels.Thegradientisalsopixelated.Thewayyourellipseis
drawn,withasinglepixelwidthmeansthatyourlocalgradienttakesononlyvaluesthatarea
multipleof45degrees:

answeredApr2'14at9:43
MSalters
93.5k 6 71 194

TheImagegradientImeanhereis,asyourfirstcase,(df/dx,df/dy)vectorineachpoint. AlbertK Apr2


'14at17:45

I'veupdatedmyoriginalpost.Myoriginaltestimageisasolidellipse.AndIdoedgedetecttogettheedge
points.Butthegradientiscalculatedusingthesolidellipse.Exceptforallthis,sinceIonlywantthe
directionofthegradient,sotheinnergradientvectorandtheoutergradientvectorarestillparalleland
shouldstillbethenormalvector,isthatright? AlbertK Apr2'14at17:50

SinceIcalculatedtheimagegradientorientationoneachpixelusingdxanddyfromSobeloperator,willthat
stillbequantizedinto45,90,135...degrees? AlbertK Apr2'14at17:52

@AlbertK:No,Sobelsmoothsthatgradientusinga3x3kernel.MSalters Apr2'14at22:42

Thisseemstobecontradictorytotheanswerfromhere,whichistheprocedureIfollowedtocalculatethe
gradientorientation:1.ComputeSobelintheXdirection(Sx).2.ComputeSobelintheYdirection(Sy).
3.Computethegradientorientationwitharctan(Sy/Sx). AlbertK Apr4'14at2:22

Ifyoufocusonellipse(noothershape),youcantreatthevalueofthepixelsoftheellipseas
massofthepoints.

ThenyoucancalculatethemomentofinertialIxx,Iyy,Ixytofindouttheangle,theta,whichcan
rotateageneralellipsebacktoacanonicalform(XXc)^2/a+(YYc)^2/b=1.

ThenyoucanfindoutXcandYcbythecenterofmass.

ThenyoucanfindoutaandbbyminXandminY.

update

Thismethodcanapplytofilledellipsetoo.

Morethanoneellipseonasingleimagewillfailunlessyousegmentthemfirst.

Letmeexplainmore,IwilluseCtorepresentcos(theta)andStorepresentsin(theta)

Afterrotationtocanonicalform,thenewXis[eq0]X=xCySandYisY=xS+yCwherexandy
areoriginalpositions.

TherotationwillgiveyouminIYY.

http://stackoverflow.com/questions/22804875/howtodetectimagegradientornormalusingopencv 3/5
18/10/2015 c++HowtodetectimagegradientornormalusingOpenCVStackOverflow

[eq1]

IYY=Sum(m*Y*Y)=Sum{m*(xS+yC)(xS+yC)}=Sum{m(xxSS+yyCC+xySC)=Ixx*S^2+
Iyy*C^2+Ixy*S*C

ForminIYY,d(IYY)/d(theta)=0thatis

2IxxSC2IyySC+Ixy(CCSS)=0

2(IxxIyy)/Ixy=(SSCC)/SC=S/C+C/S=Z+1/Z

Whileprogramming,theLHSisjustanumber,let'ssaidN

Z^2NZ+1=0

SotherearetworootsofZhencetheta,let'ssaidZ1andZ2,onewillmintheIYYandtheother
willmaxtheIYY.

pseudocode

ComputeIxx,Iyy,Ixyforaholloworfilledellipse.

Computetheta1=atan(Z1)andtheta2=atan(Z2)

PutThesetwothetaintoeq1findwhichissmaller.Thenyougettheta.

Gobacktothosenonzeropixels,transferthemtonewXandYbythethetayoufound.

FindcenterofmassXcYcandminXandminYbysort().

byhand

Ifyouneedtheoriginalequationoftheellipse

Justput[eq0]intothecanonicalform

editedApr3'14at3:54 answeredApr2'14at10:38
maythe4thbewithu
285 1 2 10

Youcanfairlyeasilyfindthemajoraxis:picktworandompointsontheedge,andseeifyoucanincrease
thedistancebetweenthembyalternatelymovingeitherpointalongtheedge.Themajoraxisisuniquein
thatitmaximizesthedistancebetweenthetwopoints,andthefunctioniscontinuous.Goodstartingpoint
candidatesarethetwoextremesineitherXorYdirection.Breaksdownsomewhatforsmall,roundellipses
duetoroundingofpixelcoordinates.Youcanalsoeasilydeterminethecircumference.Anotherapproachis
justadirectLeastSquaresonthe6parameters.MSalters Apr2'14at11:22

I'veupdatedtheoriginalpostforthis.Sorryfortheambiguousdescriptionbefore.SinceIwanttodetectan
ellipseinarathercomplicatedsceneoronanobject,therearepointsthatisnotbelongtotheellipse.That's
whyIuseRANSACtodetectanellipse,ratherthanfitanellipse. AlbertK Apr2'14at17:55

Thanksforthedetailedexplanation!Thismethodseemstobequitegooforanimagethatonlycontainone
ellipse.However,formyapplicationthereareusuallyoneellipseandotherlinesrectanglesandetc.Butstill
thanksforyourreply:) AlbertK Apr4'14at2:58

Asforyourfinalgoal,youmaytry

findContoursand[fitEllipse]inOpenCV

Thepseudocodewillbe

1)someimageprocess

2)findallcontours

3)fiteachcontoursbyfitEllipse

hereispartofcodeIusebefore

[...imageprocess....yougetabwimage]

vector<vector<Point>>contours;
findContours(bwimage,contours,CV_RETR_LIST,CV_CHAIN_APPROX_NONE);

for(size_ti=0;i<contours.size();i++)
{
size_tcount=contours[i].size();

Matpointsf;
Mat(contours[i]).convertTo(pointsf,CV_32F);
RotatedRectbox=fitEllipse(pointsf);

/*Youcanputsomelimitationaboutsizeandaspectratiohere*/
if(box.size.width>20&&
box.size.height>20&&

http://stackoverflow.com/questions/22804875/howtodetectimagegradientornormalusingopencv 4/5
18/10/2015 c++HowtodetectimagegradientornormalusingOpenCVStackOverflow
box.size.width<80&&
box.size.height<80)
{
if(MAX(box.size.width,box.size.height)>MIN(box.size.width,box.size.height)*30)
continue;
//drawContours(SrcImage,contours,(int)i,Scalar::all(255),1,8);

ellipse(SrcImage,box,Scalar(0,0,255),1,CV_AA);
ellipse(SrcImage,box.center,box.size*0.5f,box.angle,0,360,Scalar(200,255,255),
1,CV_AA);
}
}

imshow("result",SrcImage);

editedApr4'14at15:29 answeredApr3'14at3:53
maythe4thbewithu
285 1 2 10

Thislooksgood!ButhowcanIjudgewhethertheellipseIdetectedisgoodenough?Forexample,frommy
originalRANSACmethod,Icanusethenumberofpointsthatisclosetotheellipseasacriteria.Themore
pointsthebetter.Inthemethodyouproposed,howtorankthedetectedellipse?Thanks! AlbertK Apr4
'14at2:20

IwanttovoteupthisanswerbutIdon'thaveenoughreputationtodoso......sorryaboutthat. AlbertK
Apr4'14at2:21

Sinceyoupasseachcontouryoufoundtofitellipse()whichmeansallindependentobjectsafterimage
processingwillbefitted.Thevector<Point>isallpointsofaSINGLEcontour(vectorofvector<Point>isan
array/collectionofcontour,that'swhynamedcontourS).Soyouhavethefittedellipseandtheoriginal
pointsofeachcontour.Inprinciple,youcanapplysomecriteria.maythe4thbewithuApr4'14at14:55

Soyoumayusethesize(numberofpoints)ofEACHcontourtofiltertoosmall/largeobject.Theratioof
momentofinertiaIxx/IyyofEACHcontourtofilterlinesegment.fitellipse()isveryexpensivein
computationtime.Aboutthevote,Idon'tcomeforthat,sothatisnotaproblem.maythe4thbewithuApr4
'14at15:25

http://stackoverflow.com/questions/22804875/howtodetectimagegradientornormalusingopencv 5/5