培训日记7.26

目录

一、目标识别(我的绿色水

一、目标识别(我的绿色水杯)

1.头文件中各个量的定义

头文件(general.h)的代码:

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

double fps;
string FPS;
Mat src, hsv_img, mask_img, element;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
VideoCapture capture(0);
Point2f P[4];
RotatedRect rect1, rect2;

double t1;
double t2;

Point origin;
int font_face = FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;

其中第三段是图片处理时所用变量,第四段是计算fps时所用的变量,第五段是显示帧频时所用的变量。

2.图片处理

我是先将图片转为HSV格式,再将图片用inRange进行一波筛选,将图片中绿色的部分挑出来变为白色,其他颜色变为黑色。我后来发现直接这样做效果不太好,然后用dilate+erode做了一个闭运算,消除了一些噪点。

代码:

capture >> src;
cvtColor(src, hsv_img, COLOR_BGR2HSV);
inRange(hsv_img, Scalar(35, 40, 40), Scalar(77, 255, 255), mask_img);
element = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));
dilate(mask_img, mask_img, element, Point(-1, -1), 3);
erode(mask_img, mask_img, element, Point(-1, -1), 3);

3.水杯轮廓绘制

我是使用findContours函数来找到所有轮廓,然后逐个遍历,找到最大的轮廓,求最小外接矩形。然后逐个比较,找到面积最大的外接矩形。然后将矩形的四点赋值给一个PointArray,用line描出最大外接矩形的轮廓。

代码:

findContours(mask_img, contours, 3, 1, Point(0, 0));
		for (int i = 0; i < contours.size(); i++)
		{
			if (i == 0)
				rect1 = minAreaRect(contours[i]);
			else
				rect2 = minAreaRect(contours[i]);
			if (rect1.size.height * rect1.size.width < rect2.size.height * rect2.size.width)
				rect1 = rect2;
		}
		rect1.points(P);
		for (int j = 0; j <= 3; j++)
		{
			line(src, P[j], P[(j + 1) % 4], Scalar(0, 255, 255), 5);
		}

二、显示帧频

1.帧频的计算

我用的是在循环开始时求一次时间,结束前求一次时间,用两时间差除以一个转换系数得到帧频

代码:

t1 = (double)getTickCount();
......
t2 = (double)getTickCount();
fps = (t2 - t1) * 1000 / (getTickFrequency());

2.帧频转为2位小数

我用的是将double用to_string转为string,然后遍历,当遍历到小数点时,开始计数,计数大于等于2时结束遍历,把之前遍历到的char写到一个新的string里面去。

具体代码在后面具体展示。

3.帧频的类和调用

代码:

类:

class Fps
{
	double _fps;

public:
	Fps(double fps)
	{
		_fps = fps;
	};
	string to_2f()
	{
		string fps = to_string( _fps);
		int i, j = 0;
		string result = "";
		bool isfloat = false;
		for (i = 0; j < 2; i++)
		{
			if (isfloat)
				j++;
			result += fps[i];
			if (fps[i] == '.')
				isfloat = true;

		}
		return result;
	};
};

调用:

fps = (t2 - t1) * 1000 / (getTickFrequency());
Fps f1(fps);
FPS = f1.to_2f();
origin.x = 0;
origin.y = 400;
putText(src, FPS, origin, font_face, font_scale, Scalar(0, 255, 255), thickness, 8, 0);

三、所有代码

1.general.h

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

double fps;
string FPS;
Mat src, hsv_img, mask_img, element;
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
VideoCapture capture(0);
Point2f P[4];
RotatedRect rect1, rect2;

double t1;
double t2;

Point origin;
int font_face = FONT_HERSHEY_COMPLEX;
double font_scale = 2;
int thickness = 2;

2.ConsoleApplication2.cpp

#include <iostream>
#include <opencv2\opencv.hpp>
#include <string>

#include "general.h"

using namespace std;
using namespace cv;

class Fps
{
	double _fps;

public:
	Fps(double fps)
	{
		_fps = fps;
	};
	string to_2f()
	{
		string fps = to_string( _fps);
		int i, j = 0;
		string result = "";
		bool isfloat = false;
		for (i = 0; j < 2; i++)
		{
			if (isfloat)
				j++;
			result += fps[i];
			if (fps[i] == '.')
				isfloat = true;

		}
		return result;
	};
};

int main()
{
	while (true)
	{
		t1 = (double)getTickCount();
		capture >> src;
		cvtColor(src, hsv_img, COLOR_BGR2HSV);
		inRange(hsv_img, Scalar(35, 40, 40), Scalar(77, 255, 255), mask_img);
		element = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));
		dilate(mask_img, mask_img, element, Point(-1, -1), 3);
		erode(mask_img, mask_img, element, Point(-1, -1), 3);
		findContours(mask_img, contours, 3, 1, Point(0, 0));
		for (int i = 0; i < contours.size(); i++)
		{
			if (i == 0)
				rect1 = minAreaRect(contours[i]);
			else
				rect2 = minAreaRect(contours[i]);
			if (rect1.size.height * rect1.size.width < rect2.size.height * rect2.size.width)
				rect1 = rect2;
		}
		rect1.points(P);
		for (int j = 0; j <= 3; j++)
		{
			line(src, P[j], P[(j + 1) % 4], Scalar(0, 255, 255), 5);
		}
		t2 = (double)getTickCount();
		fps = (t2 - t1) * 1000 / (getTickFrequency());
		Fps f1(fps);
		FPS = f1.to_2f();
		origin.x = 0;
		origin.y = 400;
		putText(src, FPS, origin, font_face, font_scale, Scalar(0, 255, 255), thickness, 8, 0);
		cv::imshow("mask", mask_img);
		cv::imshow("src", src);
		cv::waitKey(1);
	}
}

3.效果图

四、总结与评价 

显然这个程序的缺点很多,比如对背景的要求苛刻,识别的准确度不高,水杯装水后无法准确识别,必须要手拿杯底以免干扰等等,但是我个人认为总的来说还是比较不错的一个成果,毕竟我接触计算机视觉到现在也就十几天的时间。然后就是如果要识别别的颜色的水杯,要在主程序里面把inRange中的两个Scalar改成你要识别的颜色范围,注意是hsv格式下的!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值