OpenCV实现抠图工具的代码是什么
发表于:2025-02-11 作者:千家信息网编辑
千家信息网最后更新 2025年02月11日,今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在计算机图像领域,我们经常需要做一些抠图
千家信息网最后更新 2025年02月11日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安全错误
数据库的锁怎样保障安全
ibm服务器设置管理ip
数据库表格修改一列数据
太原市网络安全和信息化
维护网络安全国家应该怎么做
缓存服务器原理
浙江智能化网络技术推荐咨询
糖豆网络技术刘军
数据库十六进制图片
网络安全设备策略配置和优化
路由器和服务器辐射
摩尔庄园kfc兑换码选错服务器
企业网络安全的设计
全球能源互联网网络安全
北京谦乐网络技术有限公司
外包工行软件开发中心笔试
灞桥区网络安全局
35岁以上软件开发
网络安全性的意义
怎么防止网络安全问题的发生
方舟建立服务器要多长时间
HCU软件开发
天津php软件开发
重庆前端软件开发哪家专业
软件开发培训经验
小米6刷服务器系统
服务器发送命令刷新页面
江苏进口计算机网络技术推广经历
sqlite数据库属于哪一类
内网服务器怎么控制多台电脑
外协配套人员网络安全管理