基于OpenCV的车辆压黄线检测

For 物联网数据处理综合实训
小学期老师出的作业,以前没接触过OpenCV,边学边做的。现在实训过了,把代码分享出来,以供大家参考。
环境:VS2013–基于对话框的MFC
方法:级联分类器和霍夫变换
思路:视频分帧->转化为灰度图像->多尺寸检测->边缘检测和霍夫变换->显示结果

#include "stdafx.h"
#include "PPByOpenCV.h"
#include "PPByOpenCVDlg.h"
#include "afxdialogex.h"
#include <iostream>
#include <string>
#include "cv.h"  
#include <stdio.h>
#include "highgui.h"  
#include <assert.h>  
#include <math.h>  
#include <SDKDDKVer.h>
#include <tchar.h>
#include<opencv2\opencv.hpp>
#include <opencv2\objdetect\objdetect.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\ml\ml.hpp>
using namespace std;
using namespace cv;
CvCapture *capture;
static CvMemStorage* storage = 0;
const char* car_name = "model.xml";
CascadeClassifier cascade;
bool is_Stop = true;
int frame_num;
int g_slider_position;           
vector <string> filelist;
void cvShowManyImages(char* title, int nArgs);
void detectAndDisplay(IplImage* img);
vector<Vec4i> Lines;
void onTrackbarSlide(int pos)
{
    cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, pos);
    frame_num = pos;                 
    return;
}
void splitIntoFrames() {
    //VideoCapture capture("F:\\1.wmv");
    capture = cvCaptureFromFile("1.wmv");
    int frames = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
    IplImage *frame, *frame_copy = 0;
    frame_num = 0;
    cascade.load(car_name);
    storage = cvCreateMemStorage(0);
    cvNamedWindow("result", 0);
    cvCreateTrackbar("pos", "result", &g_slider_position, frames, onTrackbarSlide);
    while (!is_Stop) {
        //capture >> frame;
        cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, frame_num);
        cvSetTrackbarPos("pos", "result",frame_num);
        if (!cvGrabFrame(capture))
            break;
        frame = cvRetrieveFrame(capture);
        if (!frame)
            break;
        if (!frame_copy)
            frame_copy = cvCreateImage(cvSize(frame->width*2, frame->height*2),
            IPL_DEPTH_8U, frame->nChannels);
        if (frame->origin == IPL_ORIGIN_TL)
            //cvCopy(frame, frame_copy, 0);
            cvResize(frame, frame_copy, CV_INTER_AREA);
        else
            cvFlip(frame, frame_copy, 0);
        cvResize(frame_copy, frame_copy, CV_INTER_AREA);
        IplImage *equ = cvCreateImage(cvGetSize(frame_copy), 8, 1);
        IplImage *gray = cvCreateImage(cvGetSize(frame_copy), 8, 1);
        cvCvtColor(frame_copy, gray, CV_BGR2GRAY);
        cvEqualizeHist(gray, equ);
        detectAndDisplay(frame_copy);
        frame_num += 5;

    }
    cvReleaseImage(&frame_copy);
    cvReleaseCapture(&capture);
    cvDestroyWindow("result");
    if (!filelist.empty()){
        cvShowManyImages("result", filelist.size());
    }
}
void detectAndDisplay(IplImage *img)
{
    Mat frame = cvarrToMat(img);
    bool is = false;
    vector<Rect> cars;
    Mat frame_gray;
    Point pt1;
    Point pt2;
    Rect rect = Rect(img->width / 2-20, 0, 30, img->height);
    cvtColor(frame, frame_gray, CV_BGR2GRAY);
    equalizeHist(frame_gray, frame_gray);
    cascade.detectMultiScale(frame_gray, cars, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(20, 20));
    if (frame_num<=20){
        Mat CannyImg;
        Canny(frame, CannyImg, 140, 250, 3);
        HoughLinesP(CannyImg, Lines, 1, CV_PI / 360, 170, 30, 15);
    }
    for (size_t i = 0; i < Lines.size(); i++)
    {
        if (Lines[i][0]>img->width / 4 && Lines[i][2]<img->width *3/4)
            line(frame, Point(Lines[i][0], 0), Point(Lines[i][2], img->height), Scalar(0, 255, 0), 2, 8);
    }
    for (int i = 0; i < cars.size(); i++)
    {
        pt1.x = cars[i].x;
        pt1.y = cars[i].y;
        pt2.x = (cars[i].x + cars[i].width);
        pt2.y = (cars[i].y + cars[i].height);
        rectangle(frame, pt1, pt2, Scalar(255, 255, 255), 2, 8, 0);
        if ((pt1.x + pt2.x) / 2 >= rect.x && (pt1.x + pt2.x) / 2 <= (rect.x + 40))
        {
            rectangle(frame, pt1, pt2, Scalar(0, 0, 255), 2, 8, 0);
            is = true;
        }
    }
    //rectangle(frame, line, Scalar(0, 0, 0), 3, 8, 0);
    imshow("result", frame);
    if (is){
        img = cvCloneImage(&(frame.operator IplImage()));
        string curr_filename = "F:\\test\\frame_";
        curr_filename += to_string(frame_num);
        curr_filename += ".jpg";
        cvSaveImage(curr_filename.c_str(), img);
        filelist.push_back(curr_filename);
    }

    waitKey(10);
}
void CPPByOpenCVDlg::OnBnClickedButton1()
{
    // TODO:  在此添加控件通知处理程序代码
    if (is_Stop)
    {
        SetDlgItemText(IDC_BUTTON1, L"停止检测");
        is_Stop = false;
    }
    else
    {
        SetDlgItemText(IDC_BUTTON1, L"开始检测");
        is_Stop = true;
    }
    splitIntoFrames();
}


void CPPByOpenCVDlg::OnBnClickedButton2()
{
    // TODO:  在此添加控件通知处理程序代码
    CString Dir = L"F:\\test";   //默认打开的文件路径        
    CFileDialog openFileDlg(TRUE,Dir,NULL, OFN_HIDEREADONLY | OFN_READONLY, NULL, NULL);
    openFileDlg.GetOFN().lpstrInitialDir = L"F:\\test";
    INT_PTR result = openFileDlg.DoModal();
    if (result == IDOK) {
        CString filePath = openFileDlg.GetPathName();
        DWORD dwNum = WideCharToMultiByte(CP_OEMCP, NULL, filePath, -1, NULL, NULL, 0, NULL);
        char *CString2char = new char[dwNum];
        WideCharToMultiByte(CP_OEMCP, NULL, filePath, -1, CString2char, dwNum, 0, NULL);
        Mat  image = cvLoadImage(CString2char, 1);
        imshow(CString2char, image);
    }
}
void cvShowManyImages(char* title, int nArgs)
{

    // img - Used for getting the arguments   
    IplImage *img;

    // DispImage - the image in which input images are to be copied  
    IplImage *DispImage;

    int size;
    int i;
    int m, n;
    int x, y;

    // w - Maximum number of images in a row   
    // h - Maximum number of images in a column   
    int w, h;

    // scale - How much we have to resize the image  
    float scale;
    int max;

    // If the number of arguments is lesser than 0 or greater than 12  
    // return without displaying   
    if (nArgs <= 0)
    {
        printf("Number of arguments too small....\n");
        return;
    }
    else if (nArgs > 12)
    {
        printf("Number of arguments too large....\n");
        return;
    }
    // Determine the size of the image, and the number of rows/cols  from number of arguments   
    else if (nArgs == 1)
    {
        w = h = 1;
        size = 300;
    }
    else if (nArgs == 2)
    {
        w = 2; h = 1;
        size = 300;
    }
    else if (nArgs == 3 || nArgs == 4)
    {
        w = 2; h = 2;
        size = 300;
    }
    else if (nArgs == 5 || nArgs == 6) {
        w = 3; h = 2;
        size = 200;
    }
    else if (nArgs == 7 || nArgs == 8)
    {
        w = 4; h = 2;
        size = 200;
    }
    else
    {
        w = 4; h = 3;
        size = 150;
    }

    // Create a new 3 channel image0  
    DispImage = cvCreateImage(cvSize(100 + size*w, 60 + size*h), 8, 3);

    // Used to get the arguments passed  

    // Loop for nArgs number of arguments  
    for (i = 0, m = 20, n = 20; i < nArgs; i++, m += (20 + size))
    {
        // Get the Pointer to the IplImage  
        img = cvLoadImage(filelist[i].c_str(), 1);

        // Check whether it is NULL or not  
        // If it is NULL, release the image, and return  
        if (img == 0)
        {
            cvReleaseImage(&DispImage);
            return;
        }

        // Find the width and height of the image  
        x = img->width;
        y = img->height;

        // Find whether height or width is greater in order to resize the image  
        max = (x > y) ? x : y;

        // Find the scaling factor to resize the image  
        scale = (float)((float)max / size);

        // Used to Align the images  
        if (i % w == 0 && m != 20)
        {
            m = 20;
            n += 0 + size;
        }

        // Set the image ROI to display the current image  
        //cvSetImageROI(DispImage, cvRect(m, n, (int)( x/scale ), (int)( y/scale )));  
        cvSetImageROI(DispImage, cvRect(m, n, (int)(x / scale), (int)(y / scale)));
        //      cout<<"x="<<m<<"y="<<n<<endl;  

        // Resize the input image and copy the it to the Single Big Image  
        cvResize(img, DispImage);

        // Reset the ROI in order to display the next image  
        cvResetImageROI(DispImage);
    }

    // Create a new window, and show the Single Big Image  
    //cvNamedWindow( title, 1 );  
    cvShowImage(title, DispImage);

    /*cvWaitKey(0);*/
    //cvDestroyWindow(title);  

    // End the number of arguments 
    // Release the Image Memory  
    cvReleaseImage(&DispImage);
}

程序截图
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
完整工程https://code.csdn.net/qq_29777421/ppbyopencv.git

  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 15
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值