opencv鼠标选定感兴趣区域进行目标检测

2023-10-14 12:20

本文主要是介绍opencv鼠标选定感兴趣区域进行目标检测,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文章主要对感兴趣区域ROI的操作(车辆检测)说明
车辆追踪效果
在图像处理的领域,我们常常需要去设置自己感兴趣的区域(ROI,region of interest),来专注或者简化工作过程。也就是从图像中选择的一个图像区域,这个区域是图像分析所关注的重点。我们圈定这个区域,以便进行下一步的处理.而且,使用ROI指定想读入的目标,可以减少处理时间,增加精度,给图像处理带来不小的便利。
首先我们看下任意形状图形的绘制选择:

    #include "cv.h"  #include "highgui.h"  #include <stdio.h>  #include <stdlib.h>  IplImage* inpaint_mask = 0;  IplImage* img0 = 0, *img = 0, *inpainted = 0;  CvPoint prev_pt = {-1,-1};  void on_mouse( int event, int x, int y, int flags, void* zhang)  {  if( !img )  return;  if( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON) )  prev_pt = cvPoint(-1,-1);//初始化  else if( event == CV_EVENT_LBUTTONDOWN )  prev_pt = cvPoint(x,y);  else if( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON) )  {//手一直在绘画  CvPoint pt = cvPoint(x,y);  if( prev_pt.x < 0 )  prev_pt = pt;  cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );  prev_pt = pt;  cvShowImage( "image", img );  }  }  int main( int argc, char** argv )  {  char* filename = argc >= 2 ? argv[1] : (char*)"fruits.jpg";  if( (img0 = cvLoadImage(filename,-1)) == 0 )  return 0;  printf( "Hot keys: \n"  cvNamedWindow( "image", 1 );  img = cvCloneImage( img0 );  inpainted = cvCloneImage( img0 );  inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 );  cvZero( inpaint_mask );  cvZero( inpainted );  cvShowImage( "image", img );  cvShowImage( "watershed transform", inpainted );  cvSetMouseCallback( "image", on_mouse, 0 );     }  

利用OpenCV库进行编程实现对感兴趣区域ROI的操作

例如:将小图标复制到大图像的指定位置中

使用到的函数:矩形的表示:Rect类—-》Rect(x,y,width,heigh)

对Rect类的解释:Rect类的成员变量有x、y、width、height,分别在左上角点的坐标和矩形的宽和高。
这篇文章讲述了鼠标选定一个感兴趣区域后,实现对目标的运动检测并计数的功能。
1.首先,暂停视频或者在视频流的第一帧中,画出感兴趣区域。
2. 然后扣出感兴趣区域
3.使用运动目标检测(在这里我以背景差分为例子)

    #include<opencv2/core/core.hpp>  #include<opencv2/highgui/highgui.hpp>  #include<opencv2/imgproc/imgproc.hpp>  using namespace cv;  #include<iostream>  #include<vector>  using namespace std;  /*----定义鼠标事件--画矩形区域:作用当两个车灯----*/  //第一步:全局变量  bool drawing_box = false;  bool gotBox =  false;  Rect box;  Point downPoint;  /* void mouseRectHandler(int event, int x, int y, int flags, void *param) { switch (event) { case CV_EVENT_MOUSEMOVE: if (drawing_box) { box.width = x - box.x; box.height = y - box.y; } break; case CV_EVENT_LBUTTONDOWN: drawing_box = true; box = Rect(x, y, 0, 0); break; case CV_EVENT_LBUTTONUP: drawing_box = false; gotBox = true; if (box.width < 0) { box.x += box.width; box.width *= -1; } if( box.height < 0 ) { box.y += box.height; box.height *= -1; } break; default: break; } } */  void mouseRectHandler(int event, int x, int y, int flags, void *param)  {  switch (event)  {  case CV_EVENT_MOUSEMOVE:  if (drawing_box)  {  //鼠标的移动到downPoint的右下角  if( x >=downPoint.x && y >= downPoint.y)  {  box.x = downPoint.x;  box.y = downPoint.y;  box.width = x - downPoint.x;  box.height =  y -  downPoint.y;  }  //鼠标的移动到downPoint的右上角  if( x >= downPoint.x && y <= downPoint.y)  {  box.x =  downPoint.x;  box.y = y;  box.width = x - downPoint.x;  box.height = downPoint.y - y;  }  //鼠标的移动到downPoint的左上角  if( x <= downPoint.x && y <= downPoint.y)  {  box.x = x;  box.y = y;  box.width = downPoint.x - x;  box.height = downPoint.y - y;  }  //鼠标的移动到downPoint的左下角  if( x <= downPoint.x && y >= downPoint.y)  {  box.x = x;  box.y = downPoint.y;  box.width = downPoint.x -x;  box.height = y - downPoint.y;  }  }  break;  case CV_EVENT_LBUTTONDOWN:  //按下鼠标,代表可以可以开始画矩形  drawing_box = true;  //记录起点  downPoint = Point(x,y);  break;  case CV_EVENT_LBUTTONUP:  //松开鼠标,代表结束画矩形  drawing_box = false;  gotBox = true;  break;  default:  break;  }  }  // int main(int argc,char*argv[])    int main()   {     Mat diff_thresh;VideoCapture video("1.avi");//读取视频    // VideoCapture video(argv[1]);    Mat imageROI, imageROI_BW;   //判断视频是否打开    if( !video.isOpened())    return 0;    bool flag;//视频中的第一帧    Mat firstFrame;    flag=false;   Mat frame;    Mat imageROIdf,imageROIpro,imageROIdf_BW;//读取视频的第一帧    video>>frame;    //复制到firstFrame中    frame.copyTo(firstFrame);    //register     namedWindow("video",1);    setMouseCallback("video",mouseRectHandler,NULL);    //画感兴趣区域   while(!gotBox)    {    firstFrame.copyTo(frame);    rectangle(frame,box,Scalar(255,0,0),2);//画出感兴趣区域  imshow("video",frame);    if(waitKey(50) == 'q')//---------很重要    break;    }    //remove callback    setMouseCallback("video",NULL,NULL);    Mat frame0,result;   //视频继续    for(;;)    {    //读取视频   video>>frame;  //判断是否有当前帧  if(!frame.data)  break;  //画出感兴趣区域  rectangle(frame,box,Scalar(255,255,0),2);  imshow("video",frame);  imageROI = frame(Rect(box.x, box.y, box.width, box.height));cvtColor(imageROI,frame0,CV_RGB2GRAY);//灰度化 medianBlur(frame0, frame0, 3);//中值滤波if (false == flag){imageROIpro = imageROI.clone();flag = true;}else{absdiff(imageROI, imageROIpro, imageROIdf);//帧间差分法imageROIpro = imageROI.clone();threshold(imageROIdf, imageROIdf_BW, 30, 255, 0);imshow("imageROIdf_BW", imageROIdf_BW);diff_thresh=imageROIdf_BW;cv::cvtColor(diff_thresh, diff_thresh, CV_RGB2GRAY);vector<vector<Point> > contours;  findContours(diff_thresh, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);  
//CvSeq * contour = 0; 
//  Mat contour;    
//int Num=cvFindContours( diff_thresh, storage, &contour, sizeof(CvContour), mode, CV_CHAIN_APPROX_SIMPLE); // std::cout<<"The number of Contours is:"<<Num<<std::endl; drawContours(imageROI, contours, -1, Scalar(0, 0, 255), 2);//在result上绘制轮廓  //7.查找正外接矩形  imshow("imageROI", imageROI);vector<Rect> boundRect(contours.size());  for (int i = 0; i < contours.size(); i++)  {  boundRect[i] = boundingRect(contours[i]);  rectangle(imageROI, boundRect[i], Scalar(0, 255, 0), 2);//在result上绘制正外接矩形  }   int x,y;x=contours.size();y=box.y;CvPoint point1 = cvPoint(x, y); //cout<<x;if (contours.size()>1)std::cout<<"small xuejie: "<<contours.size()<<std::endl;       //std::cout << "Contours: " << coutours.size() << std::endl; 
//  putText(imageROI,"tracking",(100,100),FONT_HERSHEY_PLAIN,2.0,(255,255,255),2,1);//cout<<contours.size();        
//4.腐蚀  /*  gray=imageROIdf_BW;std::vector<std::vector<cv::Point> > contours;  cv::findContours(gray,   contours, // a vector of contours   CV_RETR_EXTERNAL, // retrieve the external contours  CV_CHAIN_APPROX_NONE); // retrieve all pixels of each contours  // Print contours' length  std::cout << "Contours: " << contours.size() << std::endl;  std::vector<std::vector<cv::Point> >::const_iterator itContours= contours.begin();  for ( ; itContours!=contours.end(); ++itContours)   {  std::cout << "Size: " << itContours->size() << std::endl;  }  // draw black contours on white image  cv::Mat result(gray.size(),CV_8U,cv::Scalar(255));  cv::drawContours(result,contours,  -1, // draw all contours  cv::Scalar(0), // in black  1); // with a thickness of 2  cv::namedWindow("Contours");  cv::imshow("Contours",result); //if (imageROIdf_BW.data != NULL)//{//  cout << "youyidongwuti" << endl;//}*/         }imshow("imageROI", imageROI);if(waitKey(33) == 'q')    break;    }    return 0;    }    

这篇关于opencv鼠标选定感兴趣区域进行目标检测的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/210455

相关文章

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

烟火目标检测数据集 7800张 烟火检测 带标注 voc yolo

一个包含7800张带标注图像的数据集,专门用于烟火目标检测,是一个非常有价值的资源,尤其对于那些致力于公共安全、事件管理和烟花表演监控等领域的人士而言。下面是对此数据集的一个详细介绍: 数据集名称:烟火目标检测数据集 数据集规模: 图片数量:7800张类别:主要包含烟火类目标,可能还包括其他相关类别,如烟火发射装置、背景等。格式:图像文件通常为JPEG或PNG格式;标注文件可能为X

韦季李输入法_输入法和鼠标的深度融合

在数字化输入的新纪元,传统键盘输入方式正悄然进化。以往,面对实体键盘,我们常需目光游离于屏幕与键盘之间,以确认指尖下的精准位置。而屏幕键盘虽直观可见,却常因占据屏幕空间,迫使我们在操作与视野间做出妥协,频繁调整布局以兼顾输入与界面浏览。 幸而,韦季李输入法的横空出世,彻底颠覆了这一现状。它不仅对输入界面进行了革命性的重构,更巧妙地将鼠标这一传统外设融入其中,开创了一种前所未有的交互体验。 想象

基于 YOLOv5 的积水检测系统:打造高效智能的智慧城市应用

在城市发展中,积水问题日益严重,特别是在大雨过后,积水往往会影响交通甚至威胁人们的安全。通过现代计算机视觉技术,我们能够智能化地检测和识别积水区域,减少潜在危险。本文将介绍如何使用 YOLOv5 和 PyQt5 搭建一个积水检测系统,结合深度学习和直观的图形界面,为用户提供高效的解决方案。 源码地址: PyQt5+YoloV5 实现积水检测系统 预览: 项目背景

opencv 滚动条

参数介绍:createTrackbar( trackbarname , "hello" , &alpha_slider ,alpha_max ,  on_trackbar )  ;在标签中显示的文字(提示滑动条的用途) TrackbarName创建的滑动条要放置窗体的名字 “hello”滑动条的取值范围从 0 到 alpha_max (最小值只能为 zero).滑动后的值存放在

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

JavaFX应用更新检测功能(在线自动更新方案)

JavaFX开发的桌面应用属于C端,一般来说需要版本检测和自动更新功能,这里记录一下一种版本检测和自动更新的方法。 1. 整体方案 JavaFX.应用版本检测、自动更新主要涉及一下步骤: 读取本地应用版本拉取远程版本并比较两个版本如果需要升级,那么拉取更新历史弹出升级控制窗口用户选择升级时,拉取升级包解压,重启应用用户选择忽略时,本地版本标志为忽略版本用户选择取消时,隐藏升级控制窗口 2.