基于opencv的手动采集样本工具
我最近在做目标检测(Object Detection)方面的学习,由于需要检测的目标的特殊性,只能自己去搜集样本,遂写了一小段用来采集样本的代码供大家参考。
Environment
- Ubuntu 16.04
- Opencv 4.0
- IDE: Clion
Requirement
对给定的一个视频按帧播放,我们手动截取出目标,然后自动保存到指定目录中并播放下一帧直到播放结束或按ESC退出,这样便可以对自己录制的视频进行方便的手动采样得到样本进行训练。
Implementation
整体思路
具体实现
- 全局变量
名称 | 类型 | 含义 |
---|---|---|
g_rectangle | Rect类 | 记录矩形的信息 |
g_bDrawingBox | bool变量 | 是否要画矩形的标志位 |
another | bool变量 | 是否要读取下一帧的标志位 |
xo,yo | int变量 | 记录每次画矩形打左上角点 |
in | int变量 | 记录第几帧方便命名样本 |
#include <iostream>
#include <string>
#include <sstream>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(Mat& img, Rect box);
Rect g_rectangle;
bool g_bDrawingBox = false;
bool another = true;
int xo,yo,in;
RNG g_rng(12345);
Mat imageROI;
Mat imageROItmp;
- 函数实现
- 画矩形的函数,边框变变色,可以不变emmm
void DrawRectangle(Mat& img, Rect box)
{
rectangle(
img, box.tl(),
box.br(),
Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255))
);
}
- 鼠标事件处理函数
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(Mat*) param;
switch( event)
{
case EVENT_MOUSEMOVE:
{
if(g_bDrawingBox){
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x,y,0,0);
xo = x;
yo = y;
}
break;
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;
if(g_rectangle.width < 0){
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
xo = g_rectangle.x;
}
if(g_rectangle.height < 0){
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
yo = g_rectangle.y;
}
imageROI = image(Rect(xo,yo,abs(g_rectangle.width),abs(g_rectangle.height)));
resize(imageROI,imageROItmp,Size(100,100));
stringstream filename;
filename << "samples/bad/" << in << ".jpg";
// imshow("233",imageROItmp);
imwrite(filename.str(),imageROItmp);
in++;
DrawRectangle(image, g_rectangle);
another = true;
}
break;
}
}
- 主函数
int main()
{
in = 0;
g_rectangle = Rect(-1,-1,0,0);
Mat frame;
Mat tmp;
namedWindow("damn");
setMouseCallback("damn",on_MouseHandle, (void*)&tmp);
VideoCapture capture("a.mp4");
while(1)
{
if(another == true)
capture >> frame;
another = false;
if(frame.empty())
break;
resize(frame,tmp,Size(frame.cols/2,frame.rows/2));
if(g_bDrawingBox)
DrawRectangle(tmp, g_rectangle);
imshow("damn", tmp);
if(waitKey(10) == 27)
break;
}
return 0;
}