OpenCV实现抠图工具的代码是什么
发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在计算机图像领域,我们经常需要做一些抠图
千家信息网最后更新 2026年11月03日OpenCV实现抠图工具的代码是什么
今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
在计算机图像领域,我们经常需要做一些抠图的工作,将图像中的目标感兴趣区域提取出来,剔除其他冗余的背景元素,以实现计算机视觉的各项功能(如车辆检测、人脸检测等)。如果纯粹使用美图秀秀等工具类软件的话,由于工具类软件将图像处理中各种可能用到的功能都集成在了一起,所以纯粹做抠图的话效率很低。现在我们就用 OpenCV 来实现一段简易的抠图程序,只需要在画面上选定目标的感兴趣区域,该目标就会被自动按序号保存。
代码如下,同时包含有通俗易懂的注释:
#include#include #include #include #include #include // 抠图是单目标还是多目标,若为单目标请将下面这行文字取消注释,反之请注释这段文字。// #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()
看完上述内容,你们对OpenCV实现抠图工具的代码是什么有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。
图像
区域
状态
兴趣
鼠标
目标
视频
矩形
工具
坐标
指针
终点
起点
存储
代码
最大
内容
指示
样本
注释
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网科技工作委员会主任
中国互联网科技工作委员会毛军
互联网科技有限公司图片
互联网下的科技发展
上海互联网科技有限公司
科技服务与互联网
睿民互联网科技
苏州大垚互联网科技
互联网科技公司做什么
美国互联网前沿科技
滨湖区互联网智能科技产品供应
无锡溥仪互联网科技有限公司
互联网实体化科技化
互联网对科技的发展
中国科技创新与世界互联网大会
无锡工业互联网科技有限公司
上海钢联属于互联网科技股吗
扫呗互联网科技有限公司
互联网科技手机排行榜
网互联网络科技
中关村互联网 科技集团
美国互联网保险保险科技
互联网扶贫科技
天扬科技互联网广告
成都玖崟互联网科技有限公司乐商圈怎么样
花神(南京)互联网科技有限公司
和信科技工业互联网
烟台灵鸽互联网科技有限公司
图游互联网科技
2021世界互联网领先科技成果发布