RM2016視覺開源OpenCv2代碼

RM2016視覺開源OpenCv2代碼

#include<opencv2/opencv.hpp>
#include<iostream>
#include<cstdio>
#include<omp.h>
using namespace std;
using namespace cv;

#define T_ANGLE_THRE 10
#define T_SIZE_THRE 5

void brightAdjust(Mat &src, Mat &dst, double dContrast, double dBright)
{
    int nVal;
    int rowNumber = dst.rows;
    int colNumber = dst.cols*dst.channels();

        omp_set_num_threads(8);
    #pragma omp parallel for

    for (int i = 0; i < rowNumber; i++)
    {
        uchar* dstdata = dst.ptr<uchar>(i);
        uchar* srcdata = src.ptr<uchar>(i);
        for (int j = 0; j < colNumber; j++)
        {
                nVal = ((dContrast * srcdata[j]) + dBright);
                if (nVal > 255) nVal = 255;
                else if (nVal < 0) nVal = 0;
                dstdata[j] = nVal;
        }
    }
}

void getDiffImage(Mat &src1, Mat &src2, Mat &dst, int nThre)
{
    int nVal;
    int rowNumber = src1.rows;
    int colNumber = src1.cols * src1.channels();

    omp_set_num_threads(8);
#pragma omp parallel for

    for (int i = 0; i < rowNumber; i++)
    {
        uchar* srcData1 = src1.ptr<uchar>(i);
        uchar* srcData2 = src2.ptr<uchar>(i);
        uchar* dstData = dst.ptr<uchar>(i);
        for (int j = 0; j < colNumber; j++)
        {
            if (srcData1[j] - srcData2[j]> nThre)
                dstData[j] = 255;
            else
                dstData[j] = 0;
        }
    }
}

vector<RotatedRect> armorDetect(vector<RotatedRect> vEllipse)
{
    vector<RotatedRect> vRlt;
    RotatedRect armor;
    int nL, nW;
    double dAngle;
    vRlt.clear();
    if (vEllipse.size() < 2)
        return vRlt;
    for (unsigned int nI = 0; nI < vEllipse.size() -1; nI++)
    {
        for (unsigned int nJ = nI + 1; nJ < vEllipse.size(); nJ++)
        {
            dAngle = abs(vEllipse[nI].angle - vEllipse[nJ].angle);
            while (dAngle > 180)
                dAngle -= 180;
            if ((dAngle < T_ANGLE_THRE || 180 - dAngle < T_ANGLE_THRE) && abs(vEllipse[nI].size.height - vEllipse[nJ].size.height) < (vEllipse[nI].size.height + vEllipse[nJ].size.height) / T_SIZE_THRE && abs(vEllipse[nI].size.width - vEllipse[nJ].size.width) < (vEllipse[nI].size.width + vEllipse[nJ].size.width) / T_SIZE_THRE)
            {
                armor.center.x = (vEllipse[nI].center.x + vEllipse[nJ].center.x) / 2;
                armor.center.y = (vEllipse[nI].center.y + vEllipse[nJ].center.y) / 2;
                armor.angle = (vEllipse[nI].angle + vEllipse[nJ].angle) / 2;
                if (180 - dAngle < T_ANGLE_THRE)
                    armor.angle += 90;
                nL = (vEllipse[nI].size.height + vEllipse[nJ].size.height) / 2;
                nW = sqrt((vEllipse[nI].center.x - vEllipse[nJ].center.x) * (vEllipse[nI].center.x - vEllipse[nJ].center.x) + (vEllipse[nI].center.y - vEllipse[nJ].center.y) * (vEllipse[nI].center.y - vEllipse[nJ].center.y));
                if (nL < nW)
                {
                    armor.size.height = nL;
                    armor.size.width = nW;
                }
                else
                {
                    armor.size.height = nW;
                    armor.size.width = nL;
                }
                vRlt.push_back(armor);
            }
        }
    }
    return vRlt;
}

void drawBox(RotatedRect box, Mat &img)
{
    Point2f vertex[4];
    box.points(vertex);
    for (int i = 0; i < 4; i++)
    {
        line(img, vertex[i], vertex[(i + 1) % 4], Scalar(0, 0, 255), 2, CV_AA);
    }
}


int main()
{
    bool bFlag=true;
    vector<Mat> channels;
    vector<RotatedRect> vEllipse;
    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;
    vector<RotatedRect> vRlt;
    RotatedRect box;
    Point2f vertex[4];
    Mat frame,  bImage, gImage, rImage, rawImage, grayImage, rlt;
    Mat binary;
    VideoCapture cap("RedCar.avi");
    cap >> frame;
    frame.copyTo(rawImage);
    double time = 0;
    unsigned int frames=0;
    while (1)
    {
        frames++;
        double t0 = getTickCount();
        brightAdjust(frame, rawImage, 1, -120);

        split(rawImage, channels);
        bImage = channels.at(0);
        gImage = channels.at(1);
        rImage = channels.at(2);
        bImage.copyTo(binary);
        getDiffImage(rImage, gImage, binary, 25);
        Mat element = getStructuringElement(MORPH_RECT, Size(5, 5));
        dilate(binary, grayImage, element, Point(-1, -1), 3);
        erode(grayImage, rlt, element, Point(-1, -1), 1);
        findContours(rlt, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
        if (contours.size() == 0)
            continue;
        for (int i = 0; i < contours.size(); i++)
        {
            if ((contourArea(contours[i])>300 && contours.size()>10) || (contours.size()<10 && contours.size()>30) )
            {
                box = minAreaRect(Mat(contours[i])); //原代碼是用橢圓擬合,然而我的電腦上fitellipse()出錯
                box.points(vertex);
                for (int i = 0; i < 4; i++)
                    line(rlt, vertex[i], vertex[(i + 1) % 4], Scalar(255), 2, CV_AA);

                if ((box.size.height / box.size.width) > 1.0)
                    bFlag = true;
                for (int nI = 0; nI < 5; nI++)
                {
                    for (int nJ = 0; nJ < 5; nJ++)
                    {
                        if (box.center.y - 2 + nJ > 0 && box.center.y - 2 + nJ < 480 && box.center.x - 2 + nI > 0 && box.center.x - 2 + nI <  640)
                        {
                            Vec3b sx = frame.at<Vec3b>((int)(box.center.y - 2 + nJ), (int)(box.center.x - 2 + nI));
                            if (sx[0] < 200 || sx[1] < 200 || sx[2] < 200)
                            {
                                int x1 = sx[0];
                                int x2 = sx[1];
                                int x3 = sx[2];
                                bFlag = false;
                                break;
                            }
                        }
                    }
                }
                if (bFlag)
                {  
                    vEllipse.push_back(box);
                }
            }


        }
        vRlt = armorDetect(vEllipse);
        for (unsigned int nI = 0; nI < vRlt.size(); nI++)
            drawBox(vRlt[nI], frame);
        vEllipse.clear();
        vRlt.clear();

        //imshow("B", rImage);
        //imshow("G", gImage);
        //imshow("R", bImage);
        imshow("Bi", binary);
        imshow("RLT", rlt);
        imshow("frame", frame);
        //imshow("2", rawImage);

        cvWaitKey(30);
        cap >> frame;
        time += (getTickCount() - t0) / getTickFrequency();
        cout << frames / time << " fps" << endl;
    }
    return 0;
}
發佈了46 篇原創文章 · 獲贊 22 · 訪問量 8萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章