【分享帖】打杂工程师代码太坑爹?视觉开源代码opencv2版本
![kaka](https://hz-rm-bbs-web-prod.oss-cn-hangzhou.aliyuncs.com/avatar/pre/v1/000009125_avatar_big.jpg)
把视觉开源代码改写成了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;
}
#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;
}
请问这篇文章对你有用吗?
【分享帖】打杂工程师代码太坑爹?视觉开源代码opencv2版本