Skip to content

Commit

Permalink
使用OSTU方法动态获取二值化阈值,计算黑色像素比例
Browse files Browse the repository at this point in the history
本版本为比赛前的稳定加强版本,可以检测识别横向纵向信号灯
  • Loading branch information
JayYangSS committed Nov 13, 2015
1 parent 2b9678f commit bfaca4b
Show file tree
Hide file tree
Showing 7 changed files with 441 additions and 414 deletions.
30 changes: 13 additions & 17 deletions Main_TrafficSignRecognition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,12 @@ int Frame_pos;//µ±Ç°Ö¡Î»ÖÃ
bool isTrain=false;//traffic signs
bool TRAIN=false;//TL
bool HORZ=false;//TL
bool TLRecTrain=true;//是否训练信号灯识别分类器
bool saveFlag=true;
bool TLRecTrain=false;//是否训练信号灯识别分类器
//bool saveFlag=true;
Mat re_src;//for traffic signs detection
IplImage *resize_TLR=cvCreateImage(Size(800,600),8,3);

vector<Rect> found_TL;//the bounding box for traffic lights
//vector<Rect> found_TL;//the bounding box for traffic lights
vector<Rect> found_TSR;//the bounding box for traffic signs
Scalar colorMode[]={CV_RGB(255,255,0),CV_RGB(0,0,255),CV_RGB(255,0,0)};//the color mode for the traffic sign detection(Y,B,R)
CvANN_MLP nnetwork,nnetwork_RoundRim,nnetwork_RectBlue;//neural networks for three different kinds of traffic signs
Expand Down Expand Up @@ -169,9 +169,10 @@ void savePCA(string filepath,string outputPath)

void TLDetectionPerFrame(IplImage *frame,float *TLDSend)
{
IplImage *imageSeg=NULL,*imageNoiseRem =NULL;
IplImage *imageSeg=NULL;
//IplImage*imageNoiseRem =NULL;

found_TL.clear();
//found_TL.clear();
cvResize(frame,resize_TLR);
/*//此处先使用顶帽算法,再使用闭操作
IplImage* tmpGray=cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,1);
Expand All @@ -193,16 +194,11 @@ void TLDetectionPerFrame(IplImage *frame,float *TLDSend)
cvReleaseStructuringElement(&t);*/

imageSeg = colorSegmentationTL(resize_TLR);



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);


imageNoiseRem=noiseRemoval(imageSeg);
//cvShowImage("closeImg",closeImg);
//imageNoiseRem=noiseRemoval(imageSeg);
#if ISDEBUG_TL
cvNamedWindow("imgseg");
cvShowImage("imgseg",imageSeg);
Expand All @@ -213,7 +209,7 @@ void TLDetectionPerFrame(IplImage *frame,float *TLDSend)
//componentExtraction(imageNoiseRem,resize_TLR,TLDSend,found_TL);
componentExtractionTL(closeImg,resize_TLR,TLDSend);
cvReleaseImage(&imageSeg);
cvReleaseImage(&imageNoiseRem);
//cvReleaseImage(&imageNoiseRem);
cvReleaseImage(&closeImg);
}

Expand Down Expand Up @@ -657,7 +653,7 @@ 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\\TL_HORZ.avi");
CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\changshu data\\TL\\RedFalsePositive.avi");
//CvCapture * cap=cvCreateFileCapture("D:\\JY\\JY_TrainingSamples\\2014.11.16\\1_clip.mp4");
float startTime=1000*(float)getTickCount()/getTickFrequency();
CvVideoWriter * writer=NULL;
Expand Down Expand Up @@ -714,9 +710,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
517 changes: 258 additions & 259 deletions TLRec.xml

Large diffs are not rendered by default.

132 changes: 82 additions & 50 deletions TrafficLightDetection/RectangleDetection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ void GetImageRect(IplImage* orgImage, CvRect rectInImage, IplImage* imgRect)
CvSize size;
size.width=rectInImage.width;
size.height=rectInImage.height;
//result=cvCreateImage( size, orgImage->depth, orgImage->nChannels );

//从图像中提取子图像
cvSetImageROI(orgImage,rectInImage);
cvCopy(orgImage,result);
Expand Down Expand Up @@ -50,28 +50,24 @@ bool isLighInBox(Mat src)
return false;
}

bool rectangleDetection(IplImage* inputImage,IplImage* srcImage,CvRect iRect,int iColor,int* p1,int* p2)//p1为前行位,p2为左转位
void rectangleDetection(IplImage* inputImage,IplImage* srcImage,CvRect iRect,int iColor,int* p1,int* p2)//p1为前行位,p2为左转位
{

const int iWidth = inputImage->width;
const int iHeight = inputImage->height;
IplImage* imageGrayScale = cvCreateImage(cvSize(iWidth,iHeight),IPL_DEPTH_8U,1);
int iWidthStep = imageGrayScale->widthStep;
cvCvtColor(srcImage,imageGrayScale,CV_BGR2GRAY);

//水平和竖直状态
bool VerticalReturnStatus = false;
bool HorzReturnStatus=false;

//横向检测框
int HorzRectHeight=(iRect.width+iRect.height)/2 + 6;
int HorzRectWidth=3*(HorzRectHeight-4)+6;
int HorzRectWidth=3*(HorzRectHeight-4)+3;
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 grayThresholding =80;//70
const int RatioThreshold = 55;//检测框中黑色像素所占比例

//纵向检测框
Expand All @@ -89,62 +85,98 @@ bool isLighInBox(Mat src)
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;
//cvReleaseImage(&imageGrayScale);//when return the result, the image must be released, otherwise,the memory will be leaked
return;
}

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 VerticalReturnStatus;
//cvReleaseImage(&imageGrayScale);//when return the result, the image must be released, otherwise,the memory will be leaked
return;
}


//竖直方向统计黑色像素比例
CvRect VerticalRect;
VerticalRect.x=iDrawRectX1;
VerticalRect.y=iDrawRectY1;
VerticalRect.width=iDrawRectWidth;
VerticalRect.height=iDrawRectHeight;
IplImage*VerticalLight = cvCreateImage(cvSize(iDrawRectWidth,iDrawRectHeight),srcImage->depth,srcImage->nChannels);
GetImageRect(srcImage,VerticalRect,VerticalLight);
IplImage *VerticalGrayLight=cvCreateImage(cvSize(iDrawRectWidth,iDrawRectHeight),IPL_DEPTH_8U,1);
cvCvtColor(VerticalLight,VerticalGrayLight,CV_BGR2GRAY);
cvThreshold(VerticalGrayLight,VerticalGrayLight,0,255,CV_THRESH_OTSU);


/*
int iWidthStep = VerticalGrayLight->widthStep;
int sum=0;
int grayValue=0;
//int bValue=0,gValue=0,rValue=0;
//int bgrMax=0,bgrMin=0;
unsigned char* pData;
//unsigned char* pSrcData;
for(int j=iDrawRectY1; j<=iDrawRectY2; j++){
pData = (unsigned char*)imageGrayScale->imageData + j*iWidthStep;
for(int i=iDrawRectX1; i<=iDrawRectX2; i++){
grayValue = pData[i];
if((grayValue<=grayThresholding))
int VerticalGrayValue=0;
unsigned char* pDataVertical;
for(int j=0; j<iDrawRectHeight; j++){
pDataVertical = (unsigned char*)VerticalGrayLight->imageData + j*iWidthStep;
for(int i=0; i<iDrawRectWidth; i++){
VerticalGrayValue = pDataVertical[i];
if((VerticalGrayValue<=grayThresholding))
sum++;
}
}
}*/

int cvVerticalSum=cvCountNonZero(VerticalGrayLight);
int verticalBlackNum=iDrawRectWidth*iDrawRectHeight-cvVerticalSum;//黑色像素点个数
cvReleaseImage(&VerticalLight);
cvReleaseImage(&VerticalGrayLight);



//水平方向统计黑色像素比例
CvRect HorzRect;
HorzRect.x=HorzRectX1;
HorzRect.y=HorzRectY1;
HorzRect.width=HorzRectWidth;
HorzRect.height=HorzRectHeight;
IplImage*HorzLight = cvCreateImage(cvSize(HorzRectWidth,HorzRectHeight),srcImage->depth,srcImage->nChannels);
GetImageRect(srcImage,HorzRect,HorzLight);
IplImage *HorzGrayLight=cvCreateImage(cvSize(HorzRectWidth,HorzRectHeight),IPL_DEPTH_8U,1);
cvCvtColor(HorzLight,HorzGrayLight,CV_BGR2GRAY);
cvThreshold(HorzGrayLight,HorzGrayLight,0,255,CV_THRESH_OTSU);


/*
int HorzWidthStep = HorzGrayLight->widthStep;
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))
int HorzGrayValue=0;
unsigned char* pDataHorz;
for(int j=0; j<HorzRectHeight; j++){
pDataHorz = (unsigned char*)HorzGrayLight->imageData + j*HorzWidthStep;
for(int i=0; i<HorzRectWidth; i++){
HorzGrayValue = pDataHorz[i];
//if((HorzGrayValue<=grayThresholding))
if((HorzGrayValue==0))
HorzSum++;
}
}

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

//水平检测窗
HorzRectHeight=HorzRectY2-HorzRectY1;
HorzRectWidth=HorzRectX2-HorzRectX1;
} */
int cvHorzSum=cvCountNonZero(HorzGrayLight);
int horzBlackNum=HorzRectWidth*HorzRectHeight-cvHorzSum;
cvReleaseImage(&HorzLight);
cvReleaseImage(&HorzGrayLight);


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

#if ISDEBUG_TL
ofstream outfile;
Expand All @@ -165,10 +197,12 @@ bool isLighInBox(Mat src)
isLighInBox(tmpMat);
#endif

int DetectResult=isTL(srcImage,iRect);cout<<"有无信号灯:"<<DetectResult<<endl;
int DetectResult=isTL(srcImage,iRect);
if (DetectResult==1)
{
if(VerticalBlackRatio>=RatioThreshold&&VerticalBlackRatio<=90)
//cout<<"Horz Ratio:"<<HorzBlackRatio<<endl;
//cout<<"Vertical Ratio:"<<VerticalBlackRatio<<endl;
if(VerticalBlackRatio>=RatioThreshold&&VerticalBlackRatio<=93)
VerticalReturnStatus = true;
else if (HorzBlackRatio>=RatioThreshold&&HorzBlackRatio<=90)
{
Expand Down Expand Up @@ -204,9 +238,9 @@ bool isLighInBox(Mat src)
//cout<<"禁止左转"<<endl;
*p2=1;
break;
case 2://右转
case 2://前行箭头
//cout<<"禁止右转"<<endl;
//*p3=1;
*p1=1;
break;
default:
break;
Expand Down Expand Up @@ -239,16 +273,14 @@ bool isLighInBox(Mat src)
//cout<<"禁止左转"<<endl;
*p2=1;
break;
case 2://右转
case 2://前行箭头
//cout<<"禁止右转"<<endl;
//*p3=1;
*p1=1;
break;
default:
break;
}
}
}

cvReleaseImage(&imageGrayScale);
return VerticalReturnStatus;
return;
}
2 changes: 1 addition & 1 deletion TrafficLightDetection/regionGrowFiltering.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include "std_tlr.h"
#define IS_CUTIMG 1
#define IS_CUTIMG 0

extern HOGDescriptor myHOG_vertical;
extern HOGDescriptor myHOG_horz;
Expand Down
2 changes: 1 addition & 1 deletion TrafficLightDetection/std_tlr.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ IplImage* noiseRemoval2(IplImage* inputImage);
IplImage* fixImage(IplImage* colorseg,IplImage* tophat);
bool sizeFiltering(CvRect rect);
bool regionGrowFiltering(IplImage* inputImage,IplImage*colorSeg,CvRect iRect,CvRect& oRect,vector<Rect> &found_filtered);
bool rectangleDetection(IplImage* inputImage,IplImage* srcImage,CvRect iRect,int iColor,int* p1,int* p2);
void rectangleDetection(IplImage* inputImage,IplImage* srcImage,CvRect iRect,int iColor,int* p1,int* p2);
bool BoxDetectTL(Mat src_test,HOGDescriptor &myHOG,bool HORZ);
bool BlackAroundLight(IplImage* srcImg,CvRect iRect);
int RecognizeLight(IplImage* srcImg,CvRect iRect);//return the TL recognition result
Expand Down
Loading

0 comments on commit bfaca4b

Please sign in to comment.