基于opencv的样本采集工具

基于opencv的手动采集样本工具

我最近在做目标检测(Object Detection)方面的学习,由于需要检测的目标的特殊性,只能自己去搜集样本,遂写了一小段用来采集样本的代码供大家参考。

Environment

  • Ubuntu 16.04
  • Opencv 4.0
  • IDE: Clion

Requirement

对给定的一个视频按帧播放,我们手动截取出目标,然后自动保存到指定目录中并播放下一帧直到播放结束或按ESC退出,这样便可以对自己录制的视频进行方便的手动采样得到样本进行训练。

Implementation

整体思路

读取一帧视频适当resize后imshow出来
判断是否要画矩形
等待触发鼠标event
截取完了再读取下一帧
鼠标event处理函数
DOWN
MOVE
UP
按下了就画矩形
实时更新矩形长宽
告诉大家无已经按下了
开始画矩形了
截取完了注意下方向
存图下一帧

具体实现

  • 全局变量
名称类型含义
g_rectangleRect类记录矩形的信息
g_bDrawingBoxbool变量是否要画矩形的标志位
anotherbool变量是否要读取下一帧的标志位
xo,yoint变量记录每次画矩形打左上角点
inint变量记录第几帧方便命名样本
#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;
  • 函数实现
  1. 画矩形的函数,边框变变色,可以不变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))
    );
}
  1. 鼠标事件处理函数
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;

    }
}
  1. 主函数
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;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值