夜间车辆检测

// ConsoleApplication36.cpp : 定义控制台应用程序的入口点。
// ConsoleApplication29.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include
#include
#include
#include

using namespace cv;
using namespace std;
using namespace cv::xfeatures2d;

int hmin = 0;
int hmin_Max = 255;
int hmax = 255;
int hmax_Max = 255;
//饱和度 or g 
int smin = 0;
int smin_Max = 255;
int smax = 255;
int smax_Max = 255;
//亮度  or r
int vmin = 0;
int vmin_Max = 255;
int vmax = 255;
int vmax_Max = 255;
//显示原图的窗口  
string windowName = "src";
//输出图像的显示窗口  
string dstName = "dst";
//输出图像  
Mat  bgr, hsv, dst;
//回调函数  
void callBack(int, void*)
{
    //输出图像分配内存  
    //Mat    dst1 = Mat::zeros(dst.size(), CV_32FC3);
    //Mat    dst1 = Mat::zeros(dst.size(), CV_32FC3);
    Mat    dst1 = Mat::zeros(dst.size(), CV_8UC3);
    //掩码  
    Mat mask;
    //inRange(img, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);
    //inRange(hsv, Scalar(hmin, smin / float(smin_Max), vmin / float(vmin_Max)), Scalar(hmax, smax / float(smax_Max), vmax / float(vmax_Max)), mask);
    inRange(dst, Scalar(hmin, smin, vmin), Scalar(hmax, smax, vmax), mask);
    //只保留  
    for (int r = 0; r < dst.rows; r++)
    {
        for (int c = 0; c < dst.cols; c++)
        {
            if (mask.at(r, c) == 255)
            {
                dst1.at(r, c) = dst.at(r, c);
            }
        }
    }
    //输出图像  
    imshow(dstName, dst1);
    //保存图像  
    /*dst.convertTo(dst, CV_8UC3, 255.0, 0);
    imwrite("HSV_inRange.jpg", dst);*/
}

int main()
{
    VideoCapture cap("C:\\Users\\lbn\\Desktop\\夜间车辆\\6.mp4");
    while (1) {
        Mat srcImage;//= imread("C:\\Users\\lbn\\Desktop\\夜间车辆\\01.bmp");
        cap >> srcImage;
        resize(srcImage, srcImage, Size(srcImage.cols , srcImage.rows ), (0, 0), (0, 0), 3);
        Mat asd;
        srcImage.copyTo(asd);
        imshow("【原图】", srcImage);

        for (int i = 0; i < srcImage.rows; i++) {
            for (int j = 0; j < srcImage.cols; j++) {
                //检测红色区域
                if ((srcImage.at(i, j)[0] == 0) &&
                    (srcImage.at(i, j)[1] == 0))
                {

                }
                else
                {
                    srcImage.at(i, j) = 0;
                    /*srcImage.at(i, j)[0] = 0;
                    srcImage.at(i, j)[1] = 0;
                    srcImage.at(i, j)[2] = 0;*/
                }
            }
        }
        //imshow("【原图1】", srcImage);
        /*Mat grayImage;
        cvtColor(srcImage, grayImage, CV_BGR2GRAY);
        Mat cannyImage;
        Canny(grayImage, cannyImage, 0, 255, 3);
        imshow("【canny1】", cannyImage);*/
        int g_nStructElementSize = 2;
        Mat element = getStructuringElement(MORPH_RECT, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));

        dilate(srcImage, srcImage, element); dilate(srcImage, srcImage, element);// erode(srcImage, srcImage, element);
                                                                                 //imshow("【原图2】", srcImage);
        for (int i = 0; i < srcImage.rows; i++) {
            for (int j = 0; j < srcImage.cols; j++) {
                //检测红色区域
                if (srcImage.at(i, j)[2] < 80)
                    srcImage.at(i, j)[2] = 0;
            }
        }
        //imshow("【原图3】", srcImage);
        Mat grayImage;
        cvtColor(srcImage, grayImage, CV_BGR2GRAY);
        Mat cannyImage;
        threshold(grayImage, cannyImage, 0, 255, THRESH_BINARY);
        //Canny(grayImage, cannyImage, 0, 255, 3);
        imshow("【原图3】", cannyImage);
        //在二值图像中提取轮廓
        vector> contours;
        vector hierarchy;
        findContours(cannyImage, contours, hierarchy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE, Point(0, 0));
        //对每个轮廓的点集 找逼近多边形
    //    vector> approxPoint(contours.size());
        Mat drawImage = Mat::zeros(srcImage.size(), CV_8UC3);
        /*for (int i = 0; i < (int)contours.size(); i++)
        {
        approxPolyDP(contours[i], approxPoint[i], 3, true);
        
        }*/
        drawContours(drawImage, contours, -1, Scalar(255, 255, 255), 1);
        /******************************************绘制曲线的方式********************************************/
        //用绘制轮廓的函数   绘制曲线
        
        //for (int i = 0; i < (int)approxPoint.size(); i++)
        //{
            //drawContours(drawImage, contours, i, Scalar(255, 255, 255), 1);
        //    drawContours(drawImage, approxPoint, i, Scalar(255, 255, 255), 1);
        //}
            imshow("【原图4】", drawImage);
            vector boundRect(contours.size());
            //vector boundRect();
        for (int i = 0; i < (int)contours.size(); i++)
        {
            Point2f center;
            float radius;
            boundRect[i]= boundingRect(Mat(contours[i]));
            rectangle(asd, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 255), 1, 8, 0);
            minEnclosingCircle(contours[i], center, radius);
            //根据得到的圆形和半径  绘制圆形
            //circle(asd, static_cast(center), (int)radius
            //    , Scalar(0, 255, 255), 1);
            //    CvRect rect = cvBoundingRect(contours[i], 0);
            //cvRectangle(drawImage, cvPoint(rect.x, rect.y), cvPoint(rect.x + rect.width, rect.y + rect.height), CV_RGB(0, 255, 0), 1, 8, 0);
        }
        /*for (int i = 0; i < (int)approxPoint.size(); i++)
        {
            rectangle(asd, boundRect[i].tl(), boundRect[i].br(), Scalar(0, 255, 255), 1, 8, 0);
        }*/
        imshow("【原图5】", asd);
        waitKey(1);
    }
    return 0;
}

//先对图像进行空间的转换(为了之后要提取二值图像)
//Mat grayImage;
//cvtColor(srcImage, grayImage, CV_BGR2GRAY);
////对图像进行滤波,达到较好的效果
//GaussianBlur(grayImage, grayImage, Size(3, 3), 0, 0);
//imshow("【滤波后的图像】", grayImage);
//int g_nStructElementSize = 2;
//Mat element = getStructuringElement(MORPH_ELLIPSE, Size(2 * g_nStructElementSize + 1, 2 * g_nStructElementSize + 1), Point(g_nStructElementSize, g_nStructElementSize));
//erode(grayImage, grayImage, element); erode(grayImage, grayImage, element);
//dilate(grayImage, grayImage, element); dilate(grayImage, grayImage, element); dilate(grayImage, grayImage, element);
////用边缘检测的方式获取二值图像
//Mat cannyImage;
//Canny(grayImage, cannyImage, 0, 255, 3);

////在二值图像中提取轮廓
//vector> contours;
//vector hierarchy;
//findContours(cannyImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0));

////对每个轮廓的点集 找逼近多边形
//vector> approxPoint(contours.size());
//for (int i = 0; i < (int)contours.size(); i++)
//{
//    approxPolyDP(contours[i], approxPoint[i], 3, true);
//}

///******************************************绘制曲线的方式********************************************/
////用绘制轮廓的函数   绘制曲线
//Mat drawImage = Mat::zeros(srcImage.size(), CV_8UC3);
//for (int i = 0; i < (int)contours.size(); i++)
//{
//    //drawContours(drawImage, contours, i, Scalar(255, 255, 255), 1);
//    drawContours(drawImage, contours, i, Scalar(255, 255, 255), 1);
//}

////Mat    dst = Mat::zeros(srcImage.size(), CV_8UC3);
//dst = Mat::zeros(srcImage.size(), CV_8UC3);
//for (int r = 0; r < srcImage.rows; r++)
//{
//    for (int c = 0; c < srcImage.cols; c++)
//    {
//        if (drawImage.at(r, c)[0] == 255)
//        {
//            dst.at(r, c) = srcImage.at(r, c);
//        }
//    }
//}
//Point2f center;
//float radius;
//for (int i = 0; i < (int)contours.size(); i++)
//{
//    //approxPolyDP(contours[i], approxPoint[i], 3, true);
//    minEnclosingCircle(contours[i], center, radius);

//    //根据得到的圆形和半径  绘制圆形
//    circle(dst, static_cast(center), (int)radius
//        , Scalar(0, 255, 255), 3);

//}
//imshow("【绘制后的图像drawImage】", drawImage);
//imshow("【绘制后的图像dst】", dst);
////dst.convertTo(bgr, CV_32FC3, 1.0 / 255, 0);
////颜色空间转换  
////cvtColor(bgr, hsv, COLOR_BGR2HSV);
////定义输出图像的显示窗口  
//namedWindow(dstName, 0);
////调节色相 H  or b
//createTrackbar("hmin", dstName, &hmin, hmin_Max, callBack);
//createTrackbar("hmax", dstName, &hmax, hmax_Max, callBack);
////调节饱和度 S or g 
//createTrackbar("smin", dstName, &smin, smin_Max, callBack);
//createTrackbar("smax", dstName, &smax, smax_Max, callBack);
////调节亮度 V  or r
//createTrackbar("vmin", dstName, &vmin, vmin_Max, callBack);
//createTrackbar("vmax", dstName, &vmax, vmax_Max, callBack);
//callBack(0, 0);


//SimpleBlobDetector::Params params;
//size_t minRepeatability;            //2 重复的最小次数,只有属于灰度图像斑点的那些二值图像斑点数量大于该值时,该灰度图像斑点才被认为是特征点  
//float minDistBetweenBlobs;          //10 最小的斑点距离,不同二值图像的斑点间距离小于该值时,被认为是同一个位置的斑点,否则是不同位置上的斑点 

//params.filterByColor = true;        //斑点颜色的限制变量
//params.blobColor = 255;             //表示只提取黑色斑点;如果该变量为255,表示只提取白色斑点 

//                                    //阈值控制
//params.minThreshold = 50;                 //二值化的起始阈值 40
//params.maxThreshold = 255;                //二值化的终止阈值 160
//params.thresholdStep = 2;                 //二值化的阈值步长

//                                          //像素面积大小控制
//params.filterByArea = true;
//params.minArea = 50;                      //斑点的最小面积  
//params.maxArea = 18000;                   //斑点的最大面积  

//                                          //形状(凸)
//params.filterByCircularity = true;
//params.minCircularity = 0.5;                                  //斑点的最小圆度  
//params.maxCircularity = std::numeric_limits::max();    //斑点的最大圆度,所能表示的float类型的最大值                                                          //圆的凸值是1,正方形的凸值是0.785

//                                                              //形状凹
//params.filterByConvexity = false;
//params.minConvexity = 0.5;                                    //0.05f//斑点的最小凹度  
//params.maxConvexity = std::numeric_limits::max();    //斑点的最大凸度  

//                                                            //形状圆
//params.filterByInertia = false;
//params.minInertiaRatio = 0.5f;                                 //斑点的最小惯性率  圆的值为1,直线的值为0  //.05f
//params.maxInertiaRatio = std::numeric_limits::max();    //斑点的最大惯性率          

//Ptr detector1 = SimpleBlobDetector::create(params);

//vector keyPoints;
//detector1->detect(srcImage, keyPoints);
//Mat image_Star_Blob;
////drawKeypoints(image, keyPoints, image_with_keyPoints, Scalar(0, 0, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//drawKeypoints(dst, keyPoints, image_Star_Blob, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
//imshow("image_Star_Blob", image_Star_Blob);

////cout << "Blob_size 点个数:" << keyPoints.size() << endl;
////cout << "Blob_size 直径:" << keyPoints[0].size << endl;
////cout << "Blob_response 点强度:" << keyPoints[0].response << endl;
////cout << "Blob_pt 点位置:" << keyPoints[0].pt << endl;
//////cout << "keypoints _angle" << keyPoints.angle << endl;
//////cout << "keypoints_octave" << keyPoints.octave << endl;

////Mat Star_RGBrect_Blob;
////drawKeypoints(Star_RGBrect, keyPoints, Star_RGBrect_Blob, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
////imshow("Star_RGBrect_Blob", Star_RGBrect_Blob);

////Mat Star_HSVrect_Blob;
////drawKeypoints(Star_HSVrect, keyPoints, Star_HSVrect_Blob, Scalar(255, 0, 0), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
////imshow("Star_HSVrect_Blob", Star_HSVrect_Blob);

////Mat Blob_contour;
////Mat back(image.size(), CV_8UC3, Scalar(0, 0, 0));
////drawKeypoints(back, keyPoints, Blob_contour, Scalar(255, 255, 255), DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
////imshow("Blob_contour", Blob_contour);
//////圆圈的大小表示特征的重要性大小

你可能感兴趣的:(夜间车辆检测)