C++ - How To Detect Image Gradient or Normal Using OpenCV - Stack Overflow
C++ - How To Detect Image Gradient or Normal Using OpenCV - Stack Overflow
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.
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
Consideringtheupdatedimage,usethegeneralizedHoughtransform.MSalters Apr2'14at22:43
3Answers
You'reusingtermsinanunusualway.
Normallyforimages,theterm"gradient"isinterpretedasiftheimageisamathematicalfunction
f(x,y) .Thisgivesusa (df/dx,df/dy) vectorineachpoint.
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
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