RoboMaster

标题: 【分享帖】打杂工程师代码太坑爹?视觉开源代码opencv2版本 [打印本页]

作者: kaka    时间: 2016-3-8 22:56
标题: 【分享帖】打杂工程师代码太坑爹?视觉开源代码opencv2版本
把视觉开源代码改写成了2.0版本,不过找到轮廓后用椭圆拟合函数一直出错,用旋转矩形代替了后面还有一个家加了camshift跟踪的,以供参考= =。
#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-1; j++)
                {
                                //nVal = saturate_cast<uchar>((dContrast * srcdata[j]) + dBright); //严重影响效率
                                nVal = (int)(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, 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);
                rImage.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)>10)
                        //if ((contourArea(contours)>100 && contours.size()>10) || (contours.size()<10 && contours.size()>10) )
                        {
                                box = minAreaRect(Mat(contours));
                                box.points(vertex);
                                for (int i = 0; i < 4; i++)
                                        line(rlt, vertex, vertex[(i + 1) % 4], Scalar(255), 2, CV_AA);

                                //box = fitEllipse(Mat(contours)); //容易出错
                                //ellipse(rlt,box,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)
                                                        {
                                                                bFlag = false;
                                                        }
                                                }
                                        }
                                }
                                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", bImage);
                //imshow("G", gImage);
                //imshow("R", rImage);
                imshow("Bi", binary);
            imshow("RLT", rlt);
                imshow("frame", frame);
                //imshow("1", frame);
                //imshow("2", rawImage);
                //imshow("1",frame);
                cvWaitKey(30);
                cap >> frame;
                time += (getTickCount() - t0) / getTickFrequency();
                cout << frames / time << " fps" << endl;
        }
        return 0;
}


作者: 陈小小    时间: 2016-3-9 08:37
#在这里快速回复#看贴回贴是一种美德
作者: 陈小小    时间: 2016-3-9 08:38
看贴回贴是一种美德
作者: 陈小小    时间: 2016-3-9 08:38
看贴回贴是一种美德
作者: zhushuo1992    时间: 2016-3-9 14:37
楼主大牛!!!!
作者: 不减的霸气    时间: 2016-3-9 17:15
又和官方一样没注释的代码。幸好官方代码和思路都看了好几遍。才比较容易看楼主的代码
作者: DREAKER    时间: 2016-3-9 19:08
楼主好人啊
作者: kaka    时间: 2016-3-9 20:25
不减的霸气 发表于 2016-3-9 17:15
又和官方一样没注释的代码。幸好官方代码和思路都看了好几遍。才比较容易看楼主的代码 ...

就是个亮度调节然后图像作差找轮廓然后....
作者: 不减的霸气    时间: 2016-3-9 20:42
kaka 发表于 2016-3-9 20:25
就是个亮度调节然后图像作差找轮廓然后....

你要明白我接触opencv也才几天。。。。。。以前又没用过类似
作者: kewin1983    时间: 2016-3-11 18:01
VS2012+OPENCV2.4.11;
报错:
error C2664: "cv:line":不能将参数2从"cv:oint2f[4]"转换为"cv:oint"

vertex下面画着红波浪线
作者: 留住青春的赶脚    时间: 2016-3-12 14:00
没钱下载,先赞一个
作者: 爱在路上mylove    时间: 2016-3-18 09:32
0x003E0539 处有未经处理的异常(在 std2.exe 中):  0xC0000005:  读取位置 0x00000000 时发生访问冲突
作者: 爱在路上mylove    时间: 2016-3-18 10:32
kaka 发表于 2016-3-9 20:25
就是个亮度调节然后图像作差找轮廓然后....

思路具体是什么样的?大神,我还不是很明白,能否指教一二,谢谢!
作者: zjsyhsl    时间: 2016-3-19 21:36
厉害厉害
作者: 无血九痕    时间: 2016-5-4 17:04
看贴回贴是一种美德
作者: 951488363    时间: 2018-8-23 09:00
6666666666666666666666666
作者: Topn    时间: 2019-2-1 22:32
看贴回贴是一种美德
作者: Topn    时间: 2019-2-1 22:33
看贴回贴是一种美德
作者: Topn    时间: 2019-2-1 22:33
看贴回贴是一种美德
作者: Topn    时间: 2019-2-1 22:33
看贴回贴是一种美德
作者: Topn    时间: 2019-2-1 22:33
看贴回贴是一种美德
作者: ZbraGod    时间: 2019-2-10 19:14
贴回贴是一种美德




欢迎光临 RoboMaster (https://bbs.robomaster.com/) Powered by Discuz! X3.2