Skip to content

Commit

Permalink
增加检测横向信号灯的内容
Browse files Browse the repository at this point in the history
  • Loading branch information
JayYangSS committed Nov 12, 2015
1 parent 0ab3595 commit 2b9678f
Show file tree
Hide file tree
Showing 6 changed files with 294 additions and 87 deletions.
32 changes: 23 additions & 9 deletions Main_TrafficSignRecognition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ HOGDescriptor RectHOG(Size(30,50),Size(10,10),Size(5,5),Size(5,5),9,1,-1.0,0,0.2

//识别信号灯类别的HOG特征
HOGDescriptor TLRecHOG(Size(12,12),Size(6,6),Size(3,3),Size(3,3),9,1,-1.0,0,0.2,true,20);
HOGDescriptor isTLHOG(Size(12,12),Size(6,6),Size(3,3),Size(3,3),9,1,-1.0,0,0.2,true,20);//识别是否是信号灯

MySVM TriangleSVM,RoundRimSVM,RectBlueSVM;
MySVM TLRecSVM;//识别红色信号灯类别的SVM分类器
MySVM isTLSVM;//识别识别是否为信号灯的SVM分类器

int Frame_pos;//µ±Ç°Ö¡Î»ÖÃ

Expand Down Expand Up @@ -191,10 +194,14 @@ void TLDetectionPerFrame(IplImage *frame,float *TLDSend)

imageSeg = colorSegmentationTL(resize_TLR);

/*IplImage *closeImg=cvCreateImage(Size(imageSeg->width,imageSeg->height),imageSeg->depth,imageSeg->nChannels);


IplImage *closeImg=cvCreateImage(Size(imageSeg->width,imageSeg->height),imageSeg->depth,imageSeg->nChannels);
IplConvKernel *t=cvCreateStructuringElementEx(7,7,3,3,CV_SHAPE_ELLIPSE);
cvMorphologyEx(imageSeg,closeImg,NULL,t,CV_MOP_CLOSE);
cvShowImage("closeImg",closeImg);*/
cvShowImage("closeImg",closeImg);


imageNoiseRem=noiseRemoval(imageSeg);
#if ISDEBUG_TL
cvNamedWindow("imgseg");
Expand All @@ -204,9 +211,10 @@ void TLDetectionPerFrame(IplImage *frame,float *TLDSend)
cvWaitKey(5);
#endif
//componentExtraction(imageNoiseRem,resize_TLR,TLDSend,found_TL);
componentExtractionTL(imageNoiseRem,resize_TLR,TLDSend);
componentExtractionTL(closeImg,resize_TLR,TLDSend);
cvReleaseImage(&imageSeg);
cvReleaseImage(&imageNoiseRem);
cvReleaseImage(&closeImg);
}

void TSRecognitionPerFrame(IplImage *frame,float *TSRSend)
Expand Down Expand Up @@ -534,16 +542,22 @@ int main()
hogSVMTrainTL(myHOG_horz,TRAIN,HORZ);
else
hogSVMTrainTL(myHOG_vertical,TRAIN,HORZ);

//信号灯识别训练
if (TLRecTrain)
{
const String TLRecPath="D:\\JY\\JY_TrainingSamples\\TLRec";
const int TLTypeNum=3;//包括非TL
HOGTrainingTrafficSign(TLRecPath,TLRecHOG,TLTypeNum,TLREC_WIDTH,TLREC_HEIGHT,"src//TLRec.xml");
TLRecSVM.load("src//TLRec.xml");

const String isTLPath="D:\\JY\\JY_TrainingSamples\\isTL";
const int isTLNum=2;
HOGTrainingTrafficSign(isTLPath,isTLHOG,isTLNum,TLREC_WIDTH,TLREC_HEIGHT,"src//isTL.xml");
isTLSVM.load("src//isTL.xml");
}else{
TLRecSVM.load("src//TLRec.xml");
isTLSVM.load("src//isTL.xml");
}

//traffic sign training
Expand Down Expand Up @@ -643,8 +657,8 @@ void openMP_MultiThreadVideo()
bool saveFlag=false;
IplImage * frame,*copyFrame;
float connectResult[8]={0,0,0,0,0,0,0,0};
//CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\changshu data\\TL\\good5.avi");
CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\2014.11.16\\1_clip.mp4");
CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\changshu data\\TL\\TL_HORZ.avi");
//CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\2014.11.16\\1_clip.mp4");
float startTime=1000*(float)getTickCount()/getTickFrequency();
CvVideoWriter * writer=NULL;
//findColorRange();
Expand Down Expand Up @@ -700,9 +714,9 @@ void openMP_MultiThreadVideo()
cvShowImage("TL",resize_TLR);
cvWaitKey(5);
//show the detection result of TSR
namedWindow("TSR");
imshow("TSR",re_src);
waitKey(5);
//namedWindow("TSR");
//imshow("TSR",re_src);
//waitKey(5);
#endif
if (saveFlag)
{
Expand Down
131 changes: 89 additions & 42 deletions TrafficLightDetection/RectangleDetection.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
#include "std_tlr.h"
extern HOGDescriptor TLRecHOG;
extern MySVM TLRecSVM;//识别红色信号灯类别的SVM分类器

#define IS_CUTIMG 0

void GetImageRect(IplImage* orgImage, CvRect rectInImage, IplImage* imgRect)
{
Expand Down Expand Up @@ -62,38 +58,56 @@ bool isLighInBox(Mat src)
IplImage* imageGrayScale = cvCreateImage(cvSize(iWidth,iHeight),IPL_DEPTH_8U,1);
int iWidthStep = imageGrayScale->widthStep;
cvCvtColor(srcImage,imageGrayScale,CV_BGR2GRAY);


bool returnStatus = false;
bool VerticalReturnStatus = false;
bool HorzReturnStatus=false;

//横向检测框
int HorzRectHeight=(iRect.width+iRect.height)/2 + 6;
int HorzRectWidth=3*(HorzRectHeight-4)+6;
int HorzRectX1=0, HorzRectY1=0;
int HorzRectX2=0, HorzRectY2=0;


//int iSrcWidthStep = srcImage->widthStep;

//thresholding for graylevel differences between seedpoints and its neibours
const int grayThresholding =70;//70
const int RatioThreshold = 55;//检测框中黑色像素所占比例

//纵向检测框
int iDrawRectWidth = (iRect.width+iRect.height)/2 + 6;
int iDrawRectHeight = 3*(iDrawRectWidth-4)+6;
int iDrawRectX1=0, iDrawRectY1=0;
int iDrawRectX2=0, iDrawRectY2=0;

if(iColor==RED_PIXEL_LABEL){
iDrawRectY1 = iRect.y - 3;
HorzRectX1= iRect.x-3;
}
else if(iColor == GREEN_PIXEL_LABEL){
iDrawRectY1 = iRect.y-iDrawRectHeight/3*2;
HorzRectX1=iRect.x-HorzRectWidth/3*2;
}

iDrawRectY2 = iDrawRectY1 + iDrawRectHeight;
iDrawRectX1 = iRect.x-3;
iDrawRectX2 = iDrawRectX1 + iDrawRectWidth;

HorzRectX2= HorzRectX1+HorzRectWidth;
HorzRectY1= iRect.y-3;
HorzRectY2= HorzRectY1+HorzRectHeight;

if(HorzRectX1<0 || HorzRectY1<0 || HorzRectX2>=iWidth || HorzRectY2>=iHeight)
{
cvReleaseImage(&imageGrayScale);//when return the result, the image must be released, otherwise,the memory will be leaked
return HorzReturnStatus;
}

if( iDrawRectX1<0 || iDrawRectY1<0 || iDrawRectX2>=iWidth || iDrawRectY2>=iHeight)
{
cvReleaseImage(&imageGrayScale);//when return the result, the image must be released, otherwise,the memory will be leaked
return returnStatus;
return VerticalReturnStatus;
}


int sum=0;
int grayValue=0;
Expand All @@ -110,10 +124,27 @@ bool isLighInBox(Mat src)
}
}

//水平方向统计黑色像素比例
int HorzSum=0;
for(int j=HorzRectY1; j<=HorzRectY2; j++){
pData = (unsigned char*)imageGrayScale->imageData + j*iWidthStep;
for(int i=HorzRectX1; i<=HorzRectX2; i++){
grayValue = pData[i];
if((grayValue<=grayThresholding))
HorzSum++;
}
}

//竖直检测窗
iDrawRectHeight=iDrawRectY2-iDrawRectY1;
iDrawRectWidth=iDrawRectX2-iDrawRectX1;

int ratio = (float)sum*100/(float)((iDrawRectWidth+1)*((float)iDrawRectHeight+1));//矩形框中黑色像素所占比例
//水平检测窗
HorzRectHeight=HorzRectY2-HorzRectY1;
HorzRectWidth=HorzRectX2-HorzRectX1;

int VerticalBlackRatio = (float)sum*100/(float)((iDrawRectWidth+1)*((float)iDrawRectHeight+1));//矩形框中黑色像素所占比例
int HorzBlackRatio=(float)HorzSum*100/(float)((HorzRectWidth+1)*((float)HorzRectHeight+1));//矩形框中黑色像素所占比例

#if ISDEBUG_TL
ofstream outfile;
Expand All @@ -134,11 +165,20 @@ bool isLighInBox(Mat src)
isLighInBox(tmpMat);
#endif

if(ratio>=RatioThreshold&&ratio<=90&&BlackAroundLight(srcImage,iRect))
returnStatus = true;
int DetectResult=isTL(srcImage,iRect);cout<<"有无信号灯:"<<DetectResult<<endl;
if (DetectResult==1)
{
if(VerticalBlackRatio>=RatioThreshold&&VerticalBlackRatio<=90)
VerticalReturnStatus = true;
else if (HorzBlackRatio>=RatioThreshold&&HorzBlackRatio<=90)
{
HorzReturnStatus=true;
}
}


//若检测出的矩形框符合条件,则在原始图像上画出矩形标示框
if(returnStatus==true)
if(VerticalReturnStatus==true)
{
if(iColor==GREEN_PIXEL_LABEL)
{
Expand All @@ -153,34 +193,42 @@ bool isLighInBox(Mat src)


//TODO:识别信号灯指向
CvSize cutSize;
cutSize.width=iRect.width;
cutSize.height=iRect.height;
IplImage *tmpCutImg=cvCreateImage(cutSize,srcImage->depth,srcImage->nChannels);
GetImageRect(srcImage,iRect,tmpCutImg);
#if IS_CUTIMG
cvShowImage("tmpCutImg",tmpCutImg);
cvWaitKey(1);
char tmpName[100];
static int ppp=0;
ppp++;
sprintf_s(tmpName,"ImgCut//%d.jpg",ppp);
cvSaveImage(tmpName,tmpCutImg);
#endif
int result=RecognizeLight(srcImage,iRect);
switch(result)
{
case 0://圆形
//cout<<"圆形"<<endl;
*p1=1;
break;
case 1://禁止左转
//cout<<"禁止左转"<<endl;
*p2=1;
break;
case 2://右转
//cout<<"禁止右转"<<endl;
//*p3=1;
break;
default:
break;
}
}
}else if (HorzReturnStatus)
{
//横向检测
if(iColor==GREEN_PIXEL_LABEL)
{
cvRectangle(srcImage,cvPoint(HorzRectX1,HorzRectY1),cvPoint(HorzRectX2,HorzRectY2),cvScalar(0,255,0),2);
//*p2=*p2+1;
}

Mat cutMat(tmpCutImg);
Mat tmpTLRec;
vector<float> descriptor;

//识别信号灯类别
resize(cutMat,tmpTLRec,Size(TLREC_WIDTH,TLREC_HEIGHT));
TLRecHOG.compute(tmpTLRec,descriptor,Size(8,8));
int DescriptorDim=descriptor.size();
Mat SVMTriangleMat(1,DescriptorDim,CV_32FC1);
for(int i=0; i<DescriptorDim; i++)
SVMTriangleMat.at<float>(0,i) = descriptor[i];

int result=TLRecSVM.predict(SVMTriangleMat);
else if(iColor==RED_PIXEL_LABEL)
{
cvRectangle(srcImage,cvPoint(HorzRectX1,HorzRectY1),cvPoint(HorzRectX2,HorzRectY2),cvScalar(0,0,255),2);
//*p1=*p1+1;


//TODO:识别信号灯指向
int result=RecognizeLight(srcImage,iRect);
switch(result)
{
case 0://圆形
Expand All @@ -198,10 +246,9 @@ bool isLighInBox(Mat src)
default:
break;
}
cvReleaseImage(&tmpCutImg);//使用完Mat后再释放,否则与IplImage公用数据区的Mat就被清空了
}
}

cvReleaseImage(&imageGrayScale);
return returnStatus;
return VerticalReturnStatus;
}
Loading

0 comments on commit 2b9678f

Please sign in to comment.