cv_detection.cpp
Go to the documentation of this file.
00001 /*
00002 * Software License Agreement (BSD License)
00003 *Copyright (c) 2015, micROS Team
00004    http://micros.nudt.edu.cn/
00005 *All rights reserved.
00006 * Copyright (c) 2009, Willow Garage, Inc.
00007 * All rights reserved.
00008 *
00009 * Redistribution and use in source and binary forms, with or without
00010 * modification, are permitted provided that the following conditions
00011 * are met:
00012 *
00013 * * Redistributions of source code must retain the above copyright
00014 * notice, this list of conditions and the following disclaimer.
00015 * * Redistributions in binary form must reproduce the above
00016 * copyright notice, this list of conditions and the following
00017 * disclaimer in the documentation and/or other materials provided
00018 * with the distribution.
00019 * * Neither the name of Willow Garage, Inc. nor the names of its
00020 * contributors may be used to endorse or promote products derived
00021 * from this software without specific prior written permission.
00022 *
00023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034 * POSSIBILITY OF SUCH DAMAGE.
00035 */
00036 #include <iostream>
00037 #include <ros/ros.h>
00038 
00039 #include <opencv2/highgui/highgui.hpp>
00040 #include <opencv2/core/core.hpp>
00041 #include <opencv2/opencv.hpp>
00042 #include <opencv/cv.h>  
00043 #include <opencv/cvaux.h>
00044 #include <opencv/cxcore.h>
00045 #include <cv_bridge/cv_bridge.h>
00046 #include <sensor_msgs/image_encodings.h>
00047 
00048 #include <sensor_msgs/Image.h>
00049 #include <geometry_msgs/PoseStamped.h>
00050 #include <geometry_msgs/Pose2D.h>
00051 #include <image_transport/image_transport.h>
00052 #include "cv_detection.h"
00053 
00054 
00055 using namespace std;
00056 using namespace cv;
00057 
00058 
00059 DetectionCV::DetectionCV(ros::NodeHandle& nh_)
00060 :it_(nh_)
00061 {
00062     ros::NodeHandle private_nh_("~");
00063     private_nh_.param("initial_x", p_initial_x, 350);
00064     private_nh_.param("initial_y", p_initial_y, 200);
00065     private_nh_.param("initial_r", p_initial_r, 20);
00066 
00067     object.x=p_initial_x;
00068     object.y=p_initial_y;
00069 
00070     camera_sub_=it_.subscribe("/camera/image_raw", 1, &DetectionCV::object_detection, this);
00071 
00072     image_object_pub_=nh_.advertise<geometry_msgs::Pose2D>("/camera/object_position", 1, true);
00073 
00074 }
00075 
00076 DetectionCV::~DetectionCV(void)
00077 {
00078 
00079 }
00080 /*Object detection*/
00081 void DetectionCV::object_detection(const sensor_msgs::ImageConstPtr& msg)
00082 {
00083     cv_bridge::CvImagePtr cv_ptr;
00084     cv::Mat prev_image;
00085 
00086     try
00087     {
00088       cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
00089     }
00090     catch (cv_bridge::Exception& e)
00091     {
00092       ROS_ERROR("cv_bridge exception: %s", e.what());
00093       return;
00094     }
00095 
00096     IplImage UNImg=cv_ptr->image.operator _IplImage();
00097 
00098     cvShowImage("original",&UNImg);
00099     cv::waitKey(3);
00100 
00101     CV_Detect(&UNImg, object);
00102 
00103     geometry_msgs::Pose2D object_pose2D;
00104     object_pose2D.x=object.x;
00105     object_pose2D.y=object.y;
00106 
00107     image_object_pub_.publish(object_pose2D);
00108 }
00109 
00110 double DetectionCV::Sum(IplImage *srcImg,int nrow,int ncol)
00111 {
00112     double ImgSum=0;
00113     for(int i=0;i<nrow;i++)
00114     {
00115         for(int j=0;j<ncol;j++)
00116         {
00117              ImgSum+=CV_IMAGE_ELEM(srcImg,float,i,j);
00118         }
00119     }
00120 
00121     return ImgSum;
00122 }
00123 
00124 void DetectionCV::ShowIndex(int row,int col,IplImage *srcImg)
00125 {
00126     int nrow,ncol;
00127     CvSize ImageSize=cvGetSize(srcImg);
00128     while(1)
00129     {
00130         scanf("%d",&nrow);
00131         scanf("%d",&ncol);
00132         if(nrow==-1||ncol==-1)
00133             break;
00134     }
00135 }
00136 
00137 void DetectionCV::ImageConvert(IplImage *srcImg,int nrow,int ncol)
00138 {
00139     float ImageMax=0,Gain;
00140     double Gain1=1.0;
00141     IplImage* TempImage=cvCloneImage(srcImg);
00142 
00143     for(int i=0;i<nrow;i++)
00144     {
00145         for(int j=0;j<ncol;j++)
00146         {
00147             if(CV_IMAGE_ELEM(srcImg,float,i,j)>ImageMax)
00148             {
00149                 ImageMax=CV_IMAGE_ELEM(srcImg,float,i,j);
00150             }
00151         }
00152     }
00153 
00154     //cvMaxS(srcImg,Gain1,TempImage);
00155 
00156     Gain=255/ImageMax;
00157 
00158     cvSet(TempImage,cvScalar(Gain));
00159     cvMul(srcImg,TempImage,srcImg,1.0);
00160 
00161     cvReleaseImage(&TempImage);
00162 }
00163 
00164 void DetectionCV::sdf2circle(IplImage* Phi_0,int nrow,int ncol,int Next_X,int Next_Y,int r,CvSize ImgSize)
00165 {
00166     for(int i=0;i<nrow;i++)
00167     {
00168         for(int j=0;j<ncol;j++)
00169         {
00170              CV_IMAGE_ELEM(Phi_0,float,i,j)=sqrt((pow((double)(j-Next_X),2.0)+pow((double)(i-Next_Y),2.0)))-(double)r;
00171         }
00172     }
00173 }
00174 
00175 void DetectionCV::Heaviside(IplImage* phi,double epsilon,IplImage* H)
00176 {
00177     CvSize ImageSize=cvGetSize(phi);
00178 
00179     for(int i=0;i<ImageSize.height;i++)
00180     {
00181         for(int j=0;j<ImageSize.width;j++)
00182         {
00183             CV_IMAGE_ELEM(H,float,i,j)=0.5*(1+(2/3.1416)*atan(CV_IMAGE_ELEM(phi,float,i,j)/epsilon));
00184         }
00185     }
00186 
00187 }
00188 
00189 void DetectionCV::Delta(IplImage* phi,double epsilon,IplImage* Delta_h)
00190 {
00191     IplImage* TempImage=cvCloneImage(phi);
00192 
00193     cvMul(phi,phi,Delta_h,1.0);
00194     cvAddS(Delta_h,cvScalar(epsilon*epsilon),Delta_h);
00195     cvSet(TempImage,cvScalar(epsilon/3.1416));
00196     cvDiv(TempImage,Delta_h,Delta_h,1.0);
00197 
00198     cvReleaseImage(&TempImage);
00199 }
00200 
00201 void DetectionCV::NeumannBoundCond(IplImage* phi)//Make a function satisfy Neumann boundary condition
00202 {
00203     CvSize ImgSize=cvGetSize(phi);
00204     int i;
00205     int nrow=ImgSize.height,ncol=ImgSize.width;
00206     CV_IMAGE_ELEM(phi,float,0,0)       = CV_IMAGE_ELEM(phi,float,2,2);
00207     CV_IMAGE_ELEM(phi,float,0,ncol-1)  = CV_IMAGE_ELEM(phi,float,2,ncol-3);
00208     CV_IMAGE_ELEM(phi,float,nrow-1,0)  = CV_IMAGE_ELEM(phi,float,nrow-3,2);
00209     CV_IMAGE_ELEM(phi,float,nrow-1,ncol-1)  = CV_IMAGE_ELEM(phi,float,nrow-3,ncol-3);
00210     for(i=1;i<ncol-1;i++)
00211     {
00212          CV_IMAGE_ELEM(phi,float,4330,i)=CV_IMAGE_ELEM(phi,float,2,i);
00213     }
00214     for(i=1;i<ncol-1;i++)
00215     {
00216          CV_IMAGE_ELEM(phi,float,nrow-1,i)=CV_IMAGE_ELEM(phi,float,nrow-3,i);
00217     }
00218     for(i=1;i<nrow-1;i++)
00219     {
00220         CV_IMAGE_ELEM(phi,float,i,0)=CV_IMAGE_ELEM(phi,float,i,2);
00221     }
00222     for(i=1;i<nrow-1;i++)
00223     {
00224          CV_IMAGE_ELEM(phi,float,i,ncol-1)=CV_IMAGE_ELEM(phi,float,i,ncol-3);
00225     }
00226 
00227 }
00228 
00229 double DetectionCV::binaryfit_C1(IplImage* Img,IplImage* H_phi,int nrow,int ncol)
00230 {
00231     IplImage* a=cvCloneImage(Img);
00232     double numer_1,denom_1,C1;
00233 
00234     cvMul(H_phi,Img,a,1.0);
00235 
00236     numer_1=Sum(a,nrow,ncol);
00237     denom_1=Sum(H_phi,nrow,ncol);
00238     C1=numer_1/denom_1;
00239 
00240     cvReleaseImage(&a);
00241     return C1;
00242 }
00243 
00244 double DetectionCV::binaryfit_C2(IplImage* Img,IplImage* H_phi,int nrow,int ncol)
00245 {
00246     IplImage* a=cvCloneImage(Img);
00247     double numer_1,denom_1,C2;
00248     cvSubRS(H_phi,cvScalar(1.0),H_phi);
00249     cvMul(H_phi,Img,a);
00250     numer_1=Sum(a,nrow,ncol);
00251     denom_1=Sum(H_phi,nrow,ncol);
00252     C2=numer_1/denom_1;
00253 
00254     cvReleaseImage(&a);
00255     return C2;
00256 }
00257 /*Chan-Vese model-based image segmentation*/
00258 void DetectionCV::EVOL_CV(IplImage* I,IplImage* phi,double nu,double lambda_1,double lambda_2,double timestep,double epsilon,int numIter)
00259 {
00260     IplImage *Hphi=cvCloneImage(phi);
00261     IplImage *kappa=cvCloneImage(phi);
00262     IplImage *diracPhi=NULL,*I_C1=NULL,*I_C2=NULL,*lambda1=NULL,*lambda2=NULL,*Times=NULL;
00263     double C1,C2;
00264     CvSize ImgSize=cvGetSize(I);
00265     int nrow=ImgSize.height,ncol=ImgSize.width;
00266 
00267     I_C1=cvCloneImage(I);
00268     I_C2=cvCloneImage(I);
00269     diracPhi=cvCloneImage(I);
00270     lambda1=cvCloneImage(I);
00271     lambda2=cvCloneImage(I);
00272     Times=cvCloneImage(I);
00273 
00274     for(int i=0;i<numIter;i++)
00275     {
00276         NeumannBoundCond(phi);
00277 
00278         Delta(phi,epsilon,diracPhi);
00279 
00280         Heaviside(phi, epsilon,Hphi);
00281 
00282         C1=binaryfit_C1(I,Hphi,nrow,ncol);
00283 
00284         C2=binaryfit_C2(I,Hphi,nrow,ncol);
00285 
00286         cvSubS(I,cvScalar(C1),I_C1);
00287         cvPow(I_C1,I_C1,2.0);
00288         cvSet(lambda1,cvScalar(lambda_1));
00289         cvMul(lambda1,I_C1,I_C1);
00290         cvSubRS(I_C1,cvScalar(nu),I_C1);
00291 
00292         cvSubS(I,cvScalar(C2),I_C2);
00293         cvPow(I_C2,I_C2,2.0);
00294         cvSet(lambda2,cvScalar(lambda_2));
00295         cvMul(lambda2,I_C2,I_C2);
00296         cvAdd(I_C1,I_C2,I_C1);
00297         cvMul(diracPhi,I_C1,diracPhi);
00298         cvSet(Times,cvScalar(timestep));
00299         cvMul(Times,diracPhi,Times);
00300         cvAdd(phi,Times,phi);
00301     }
00302 
00303     cvReleaseImage(&diracPhi);
00304     cvReleaseImage(&Hphi);
00305     cvReleaseImage(&kappa);
00306     cvReleaseImage(&I_C1);
00307     cvReleaseImage(&I_C2);
00308     cvReleaseImage(&lambda1);
00309     cvReleaseImage(&lambda2);
00310     cvReleaseImage(&Times);
00311 
00312 }
00313 
00314 void DetectionCV::ImageProcess_1(IplImage* phi,int nrow,int ncol)
00315 {
00316     for(int i=0;i<nrow;i++)
00317     {
00318         for(int j=0;j<ncol;j++)
00319         {
00320             if(CV_IMAGE_ELEM(phi,float,i,j)<0)
00321             {
00322                 CV_IMAGE_ELEM(phi,float,i,j)=-CV_IMAGE_ELEM(phi,float,i,j);
00323                 if(CV_IMAGE_ELEM(phi,float,i,j)>255)
00324                     CV_IMAGE_ELEM(phi,float,i,j)=255;
00325             }
00326             else
00327                 CV_IMAGE_ELEM(phi,float,i,j)=0;
00328         }
00329     }
00330 
00331 }
00332 /*Circling the UAV*/
00333 void DetectionCV::PlanePoint(IplImage* ProcessImg_1,IplImage* SImg,int nrow,int ncol,CvPoint &PlanePoint)
00334 {
00335     int num=0,SumRow=0,SumCol=0,AveRow=0,AveCol=0;
00336     for(int i=0;i<nrow;i++)
00337     {
00338         for(int j=0;j<ncol;j++)
00339         {
00340             if(CV_IMAGE_ELEM(ProcessImg_1,float,i,j)!=0&&CV_IMAGE_ELEM(SImg,float,i,j)>200)
00341             {
00342                 num++;
00343                 SumRow+=i;
00344                 SumCol+=j;
00345             }
00346         }
00347     }
00348     if(num!=0)
00349     {
00350         AveRow=SumRow/num;
00351         AveCol=SumCol/num;
00352         PlanePoint.x=AveCol;
00353         PlanePoint.y=AveRow;
00354         //cout<<PlanePoint.x<<","<<PlanePoint.y<<endl;
00355     }
00356     else
00357     {
00358         PlanePoint.x=0;
00359         PlanePoint.y=0;
00360         ROS_WARN("No Such Point");
00361     }
00362 }
00363 
00364 void DetectionCV::CV_Detect(IplImage* UNImg,CvPoint &Plane)
00365 {
00366     IplImage *phi_0=NULL,*phi=NULL;
00367     IplImage *floatUNImg=NULL,*HSVImg=NULL,*SImg=NULL,*HImg=NULL,*VImg=NULL;
00368     CvSize ImgSize;
00369     int nrow,ncol;
00370     int Next_X=Plane.x;
00371     int Next_Y=Plane.y;
00372     int r;
00373     int i,m,n;
00374     int numIter;
00375     int HeadNum,LastHeadNum;
00376     double nu,lambda_1,lambda_2,timestep,epsilon;
00377     float index1,index2;
00378 
00379     LastHeadNum=0;
00380     numIter=10;
00381     nu = 0.001*255*255;
00382     lambda_1=1;
00383     lambda_2=1;
00384     epsilon=1;
00385     timestep=0.8;
00386 
00387     ImgSize=cvGetSize(UNImg);
00388     nrow=ImgSize.height;
00389     ncol=ImgSize.width;
00390 
00391     floatUNImg=cvCreateImage(ImgSize,IPL_DEPTH_32F,3);
00392     HSVImg=cvCreateImage(ImgSize,IPL_DEPTH_32F,3);
00393     SImg=cvCreateImage(ImgSize,IPL_DEPTH_32F,1);
00394     phi_0 = cvCloneImage(SImg);
00395     phi = cvCloneImage(SImg);
00396 
00397     cvConvertScale(UNImg,floatUNImg,1.0/255.0,0);
00398 
00399     cvCvtColor(floatUNImg,HSVImg,CV_BGR2HSV);
00400 
00401     cvSplit(HSVImg,HImg,SImg,VImg,NULL);
00402 
00403     ImageConvert(SImg,nrow,ncol);
00404 
00405     sdf2circle(phi,nrow,ncol,Next_X,Next_Y,p_initial_r,ImgSize);
00406 
00407 
00408     for(i=0;i<numIter;i++)
00409     {
00410         EVOL_CV(SImg,phi,nu,lambda_1, lambda_2, timestep, epsilon, 1);
00411 
00412         HeadNum=0;
00413 
00414         for(m=0;m<nrow;m++)
00415         {
00416             for(n=0;n<ncol;n++)
00417             {
00418                 index1=CV_IMAGE_ELEM(phi,float,m,n);
00419                 index2=CV_IMAGE_ELEM(SImg,float,m,n);
00420 
00421                 if(CV_IMAGE_ELEM(phi,float,m,n)<=0)
00422                     if(CV_IMAGE_ELEM(SImg,float,m,n)>=200)
00423                          HeadNum++;
00424             }
00425         }
00426         if(abs(HeadNum-LastHeadNum)<=0&&HeadNum>10)
00427         {
00428             r=HeadNum/4;
00429             if(r>20)
00430                 r=20;
00431             if(r<5)
00432                 r=5;
00433             break;
00434         }
00435         LastHeadNum=HeadNum;
00436 
00437     }
00438 
00439     cvCircle(UNImg,Plane,20,CV_RGB(255,0,0),2,8,0);
00440     ImageProcess_1(phi,nrow,ncol);
00441 
00442     PlanePoint(phi,SImg,nrow,ncol,Plane);
00443 
00444     cvCircle(UNImg,Plane,2,CV_RGB(0,255,0),2,8,0);
00445 
00446     cvShowImage("Result",UNImg);
00447     waitKey();
00448     cvReleaseImage(&phi_0);
00449     cvReleaseImage(&phi);
00450     cvReleaseImage(&floatUNImg);
00451     cvReleaseImage(&HSVImg);
00452     cvReleaseImage(&HImg);
00453     cvReleaseImage(&SImg);
00454     cvReleaseImage(&VImg);
00455 
00456 }
00457 
00458 


micros_cv_detection
Author(s): Dengqing Tang
autogenerated on Thu Jun 6 2019 21:36:21