iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >OpenCV实现抠图工具
  • 120
分享到

OpenCV实现抠图工具

2024-04-02 19:04:59 120人浏览 安东尼
摘要

本文实例为大家分享了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()

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

--结束END--

本文标题: OpenCV实现抠图工具

本文链接: https://www.lsjlt.com/news/162965.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • OpenCV实现抠图工具
    本文实例为大家分享了OpenCV实现抠图工具的具体代码,供大家参考,具体内容如下 在计算机图像领域,我们经常需要做一些抠图的工作,将图像中的目标感兴趣区域提取出来,剔除其他冗余的背景...
    99+
    2022-11-13
  • OpenCV实现抠图工具的代码是什么
    今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在计算机图像领域,我们经常需要做一些抠图的工作,将图像中的目标感兴趣区域提取出来...
    99+
    2023-06-26
  • 基于OpenCV-python3实现抠图
    在上一篇博客进行了证件照更换背景颜色,纯蓝色,红色,白色之间的替换,有人私信我,可以不可以把背景换成其他图片,而不是单纯的颜色填充。这在photoshop里面就是选中一个图层然后复制到另外一张图片上去,用代码实现的话和上篇博文换...
    99+
    2023-01-31
    抠图 OpenCV
  • Python抠图:使用OpenCV实现背景去除
    一、了解抠图和OpenCV库 抠图(Matting)是图像处理领域的重要任务之一,旨在将对象与其它部分分离。OpenCV是一个开源计算机视觉库,它提供了丰富的函数和工具进行图像编辑处理,可以简单而快速地实现抠图功能,同时可以进行更多的图像处...
    99+
    2023-09-28
    python opencv 开发语言
  • OpenCV如何使用GrabCut实现抠图功能
    这篇文章主要介绍“OpenCV如何使用GrabCut实现抠图功能”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“OpenCV如何使用GrabCut实现抠图功能”文章能帮助大家解决问题。1、概述案例:使...
    99+
    2023-07-05
  • Stable Diffusion 抠图工具使用小记
          用stable diffusion有段时间了,最近使用了它的抠图工具 (Remove background)。这里是我对该工具的使用和记录。希望可以帮其他人了解相关内容。文末附100个Lora资源方便大家使用。    ...
    99+
    2023-09-20
    stable diffusion 计算机视觉 人工智能
  • python opencv背景减去法抠图实现示例
    目录导包导图预处理二值化图像边缘检测填充轮廓并制作掩模保存导包 import cv2 from matplotlib import pyplot as plt import nump...
    99+
    2022-11-11
  • 使用python和opencv的mask实现抠图叠加
    背景照片: logo: 合成效果: 代码: import cv2 as cv, numpy as np # Load two images img1 = cv.imread...
    99+
    2022-11-12
  • OpenCV中怎么使用GrabCut实现抠图功能
    这篇文章主要讲解了“OpenCV中怎么使用GrabCut实现抠图功能”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“OpenCV中怎么使用GrabCut实现抠图功能”吧!1、概述grabCut...
    99+
    2023-07-05
  • C++ opencv如何利用grabCut算法实现抠图
    今天小编给大家分享一下C++ opencv如何利用grabCut算法实现抠图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2023-06-30
  • C++ opencv利用grabCut算法实现抠图示例
    目录前言一、grabCut函数二、compare函数三、代码前言 grabCut算法利用了图像中的纹理(颜色)信息和边界(反差)信息,只用少量的用户交互操作,即可得到比较好的分割结果...
    99+
    2022-11-13
  • python实现抠图
    import numpy as np import cv2 from matplotlib import pyplot as plt img = cv2.imread('b.jpg') mask = np.zeros(img.sh...
    99+
    2023-01-31
    抠图 python
  • 如何使用python和opencv的mask实现抠图叠加
    小编给大家分享一下如何使用python和opencv的mask实现抠图叠加,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!python的数据类型有哪些python的...
    99+
    2023-06-14
  • OpenCV实现简单套索工具
    Photoshop中的套索工具通过鼠标多次点击可以选中一个任意多边形的区域,然后单独对这块区域进行编辑,下面就使用OpenCV实现一个简单的功能,模拟Photoshop中的套索工具。...
    99+
    2022-11-13
  • OpenCV+Qt实现图像处理操作工具的示例代码
    目录一、目标二、使用Qt界面三、图像处理操作完整代码一、目标 Qt界面实现 雪花屏 高斯模糊 中值滤波 毛玻璃 灰度化 XY方向模糊 双边模糊 腐蚀 [图像处理操作] 要求左边原图,...
    99+
    2022-11-13
    OpenCV Qt图像处理 OpenCV 图像处理 Qt 图像处理
  • AndroidOpenGLES实现简单绿幕抠图
    目录正文OES FilterBlendShader Filter最后的效果缺陷正文 实现绿幕抠图,其实想法很简单。 这里简单粗暴的使用着色器替换。 OES Filter 直接实现在...
    99+
    2022-11-13
  • OpenCV是怎么实现简单套索工具
    这篇文章将为大家详细讲解有关OpenCV是怎么实现简单套索工具,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Photoshop中的套索工具通过鼠标多次点击可以选中一个任意多边形的区域,然后单...
    99+
    2023-06-26
  • Unity实现切割图集工具
    本文实例为大家分享了Unity实现切割图集工具的具体代码,供大家参考,具体内容如下 操作步骤 先将脚本拖入Editor 1.选中要切割的图片,texture type 选为defau...
    99+
    2022-11-12
  • Android实现折线图小工具
    本文实例为大家分享了Android实现折线图小工具的具体代码,供大家参考,具体内容如下 1.LineChart类 public class LineChart extends Vie...
    99+
    2022-11-13
  • Python实现一键抠图的示例代码
    目录需求来源实现方法需求来源 好友 A:橡皮擦,可否提供网页,上传带人像的图片,然后可以直接抠图,最好直接生成 PNG 图片下载。 橡皮擦:每天需要调用多少次? 好友 A:大概 10...
    99+
    2022-11-11
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作