OpenCV实现抠图工具的代码是什么
发表于:2024-11-23 作者:千家信息网编辑
千家信息网最后更新 2024年11月23日,今天就跟大家聊聊有关OpenCV实现抠图工具的代码是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。在计算机图像领域,我们经常需要做一些抠图
千家信息网最后更新 2024年11月23日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安全错误
数据库的锁怎样保障安全
浪潮集团软件开发笔试题
铜陵市政府网络安全宣传周
网络安全编程试卷
vue发布windows服务器
柳州天气预报软件开发
广发银行数据库查询异常
打卡系统数据库设置
云末的服务器地址
26岁软件开发
搞嵌入式软件开发
侦查系统正版软件开发公司
网络安全多形式宣传
科技互联网的趋势
服务器共享文件夹有重复的文件名
数据库助学金管理系统
锐捷云课堂服务器要不要关机
软件开发项目服务总结报告
软件开发工资一般用多少
磐安软件开发有限公司
翼龙网络技术有限公司
知名的iphone服务器托管
维护国家网络安全需要全民参与
网络安全活动通知稿
深圳用哪些打车软件开发
spring注解导入数据库类
现代通信网络技术实训
qq可用代理服务器
问道经典服务器bb升级
昌平区技术软件开发平台
post上传图片到php服务器