我的编程空间,编程开发者的网络收藏夹
学习永远不晚

OpenCV实现抠图工具

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

OpenCV实现抠图工具

本文实例为大家分享了OpenCV实现抠图工具的具体代码,供大家参考,具体内容如下

在计算机图像领域,我们经常需要做一些抠图的工作,将图像中的目标感兴趣区域提取出来,剔除其他冗余的背景元素,以实现计算机视觉的各项功能(如车辆检测、人脸检测等)。如果纯粹使用美图秀秀等工具类软件的话,由于工具类软件将图像处理中各种可能用到的功能都集成在了一起,所以纯粹做抠图的话效率很低。现在我们就用 OpenCV 来实现一段简易的抠图程序,只需要在画面上选定目标的感兴趣区域,该目标就会被自动按序号保存。

代码如下,同时包含有通俗易懂的注释:

#include <io.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <opencv.hpp>
 
// 抠图是单目标还是多目标,若为单目标请将下面这行文字取消注释,反之请注释这段文字。
// #define SINGLE_OBJECT
 
#define TRUE 1     // 逻辑真
#define FALSE 0   // 逻辑假
 
#define CODE_ESC 27     // ESC 键的编码
#define CODE_SPC 32    // 空格键的编码
 
#define STATUS_WAIT 0  // 抠图等待状态
#define STATUS_PROC 1     // 抠图进行状态
#define STATUS_DONE 2    // 抠图完成状态
 
#define VIDEO_FILENAME "capture-1.mp4"          // 视频流文件名
 
static int m_x1     = 0;    // 鼠标指针坐标(起点 x)
static int m_x2     = 0;    // 鼠标指针坐标(终点 x)
static int m_y1     = 0;    // 鼠标指针坐标(起点 y)
static int m_y2     = 0;     // 鼠标指针坐标(终点 y)
static int m_status = STATUS_WAIT;              // 当前抠图状态指示
 
static void on_mouse(int, int, int, int, void*);// 鼠标回调
 
// 主程序
int main(void)
{
    int        end    = 0;         // 指示是否结束程序
    int        next   = 0;         // 指示是否切换到下一张图片
    int        code   = 0;        // 存储按键编码
    int        count  = 0;        // 存储目标计数
    int        frame  = 0;         // 视频帧号(用于间隔采样)
    int        maxCol = 0;             // 图像最大列数(= 图像宽度 - 1)
    int        maxRow = 0;                      // 图像最大行数(= 图像高度 - 1)
    CvCapture* pVideo = NULL;          // 视频流对象
    IplImage*  pFrame = NULL;           // 视频帧图像(用于样本存储)
    IplImage*  pFrmCp = NULL;           // 视频帧图像(用于屏幕显示)
    CvPoint    pt1    = cvPoint(0, 0);          // 矩形框对角坐标点 1
    CvPoint    pt2    = cvPoint(0, 0);          // 矩形框对角坐标点 2
    CvRect     r      = cvRect(0, 0, 0, 0);     // 感兴趣区域矩形框
    char       seq[]  = "-2147483648";          // 目标计数的字串形式
    char       fil[]  = "data\\-2147483648.jpg";// 文件名字串
 
    // 载入视频流
    pVideo = cvCreateFileCapture(VIDEO_FILENAME);
    if (!pVideo)
    {
        return -1;
    } // if (!pVideo)
 
    // 创建数据存储目录
    if (_access("data", 0) != 0)
    {
        system("md data");
    } // if (_access())
 
    // 获取首帧图像,并创建拷贝,同时得到最大列数和行数,方便之后使用
    pFrame = cvQueryFrame(pVideo);
    if (pFrame)
    {
        pFrmCp = cvCreateImage(cvGetSize(pFrame), 8, pFrame->nChannels);
        maxCol = pFrmCp->width - 1;
        maxRow = pFrmCp->height - 1;
    } // if (pFrame)
    else
    {
        cvReleaseCapture(&pVideo);
        return -1;
    } // else
 
    // 设置显示窗口,并设置鼠标回调
    cvNamedWindow("Monitor", CV_WINDOW_AUTOSIZE);
    cvSetMouseCallback("Monitor", on_mouse, NULL);
 
    // 其他初始化
    end = FALSE;
    count = 0;
    frame = 0;
 
    while (!end && pFrame)
    {
        next = FALSE;
        while (!next && !end)
        {
            // 将原始视频图像复制到拷贝区域中(清除已将图像进行污染的线条、矩形框等)
            cvCopy(pFrame, pFrmCp, NULL);
            if (STATUS_WAIT == m_status)
            {
                // 等待抠图状态。画出横向和纵向的参考线
                cvLine(pFrmCp, cvPoint(m_x1, 0), cvPoint(m_x1, maxRow), CV_RGB(0, 255, 0));
                cvLine(pFrmCp, cvPoint(0, m_y1), cvPoint(maxCol, m_y1), CV_RGB(0, 255, 0));
            } // if (STATUS_WAIT)
            else if (STATUS_PROC == m_status)
            {
                // 抠图过程中。画出当前选定的感兴趣区域
                pt1 = cvPoint(m_x1, m_y1);
                pt2 = cvPoint(m_x2, m_y2);
                cvRectangle(pFrmCp, pt1, pt2, CV_RGB(0, 255, 0));
            } // else if (STATUS_PROC)
            else if (STATUS_DONE == m_status)
            {
                // 抠图完毕,获得感兴趣区域并按编号保存样本
                r = cvRect(
                    m_x1,
                    m_y1,
                    m_x2 - m_x1 + 1,
                    m_y2 - m_y1 + 1
                    ); // 矩形感兴趣区域
                if (r.width > 30 && r.height > 30)
                {
                    // 区域达到了一定大小,抠图有效,保存感兴趣区域样本
                    ++count;
                    cvSetImageROI   (pFrame, r);
                    sprintf_s       (seq, "%d", count);
                    strcpy_s        (fil, "data\\");
                    strcat_s        (fil, seq);
                    strcat_s        (fil, ".jpg");
                    cvSaveImage     (fil, pFrame, 0);
                    cvResetImageROI (pFrame);
 
#ifdef SINGLE_OBJECT
                    m_next = TRUE;
#endif
                } // if (r.width)
                
                // 恢复抠图等待状态
                m_status = STATUS_WAIT;
            } // else if (STATUS_DONE)
 
            cvShowImage("Monitor", pFrmCp);
            code = cvWaitKey(10);
            if (CODE_SPC == code)
            {
                next = TRUE;
            } // if (CODE_SPC)
            else if (CODE_ESC == code)
            {
                end = TRUE;
            } // else if (CODE_ESC)
        } // while (!next)
 
        if (next)
        {
            do
            {
                pFrame = cvQueryFrame(pVideo);
                ++frame;
            } while (pFrame && frame % 60 != 0); // do...while
        } // if (next)
    } // while (!end)
 
    cvDestroyAllWindows();
    cvReleaseImage(&pFrmCp);
    cvReleaseCapture(&pVideo);
 
    return 0;
} // main()
 
 
// 鼠标事件回调
void on_mouse(int event, int x, int y, int flags, void* param)
{
    switch (flags)
    {
    case CV_EVENT_MOUSEMOVE:
        if (STATUS_WAIT == m_status)
        {
            // 等待状态,确定感兴趣区域起点
            m_x1 = x, m_y1 = y;
        } // if (STATUS_WAIT)
        else if (STATUS_PROC == m_status)
        {
            // 捕捉状态,确定感兴趣区域终点
            m_x2 = x, m_y2 = y;
        } // else if (STATUS_PROC)
        break;
 
    case CV_EVENT_LBUTTONDOWN:
        if (STATUS_WAIT == m_status)
        {
            // 等待状态按下鼠标,进入捕捉状态,固定起点
            m_x1 = x, m_y1 = y;
            m_status = STATUS_PROC;
        } // if (STATUS_WAIT)
        else if (STATUS_PROC == m_status)
        {
            // 捕捉状态按下鼠标,捕捉完成,固定终点
            m_x2 = x, m_y2 = y;
            m_status = STATUS_DONE;
        } // else if (STATUS_PROC)
        break;
    } // switch
} // on_mouse()

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

OpenCV实现抠图工具

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

OpenCV实现抠图工具的代码是什么

今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在计算机图像领域,我们经常需要做一些抠图的工作,将图像中的目标感兴趣区域提取出来
2023-06-26

基于OpenCV-python3实现抠图

在上一篇博客进行了证件照更换背景颜色,纯蓝色,红色,白色之间的替换,有人私信我,可以不可以把背景换成其他图片,而不是单纯的颜色填充。这在photoshop里面就是选中一个图层然后复制到另外一张图片上去,用代码实现的话和上篇博文换纯色背景思路
2023-01-31

OpenCV如何使用GrabCut实现抠图功能

这篇文章主要介绍“OpenCV如何使用GrabCut实现抠图功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“OpenCV如何使用GrabCut实现抠图功能”文章能帮助大家解决问题。1、概述案例:使
2023-07-05

C++ opencv如何利用grabCut算法实现抠图

今天小编给大家分享一下C++ opencv如何利用grabCut算法实现抠图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前
2023-06-30

OpenCV中怎么使用GrabCut实现抠图功能

这篇文章主要讲解了“OpenCV中怎么使用GrabCut实现抠图功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“OpenCV中怎么使用GrabCut实现抠图功能”吧!1、概述grabCut
2023-07-05

python实现抠图

import numpy as npimport cv2from matplotlib import pyplot as plt img = cv2.imread('b.jpg')mask = np.zeros(img.shape[:2]
2023-01-31

如何使用python和opencv的mask实现抠图叠加

小编给大家分享一下如何使用python和opencv的mask实现抠图叠加,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!python的数据类型有哪些?python
2023-06-14

OpenCV+Qt实现图像处理操作工具的示例代码

这篇文章主要介绍了利用OpenCV+Qt实现图像处理操作工具,可以实现雪花屏、高斯模糊、中值滤波、毛玻璃等操作,感兴趣的可以了解一下
2022-11-13

OpenCV是怎么实现简单套索工具

这篇文章将为大家详细讲解有关OpenCV是怎么实现简单套索工具,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Photoshop中的套索工具通过鼠标多次点击可以选中一个任意多边形的区域,然后单
2023-06-26

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录