您的位置:首页 > 其它

在一幅图片上用鼠标划取多个感兴趣区域并保存下来

2017-03-30 17:52 274 查看
//用鼠标划取样本上的感兴趣区域的样本,并将样本保存下来,比较实用的一个小程序,可以在样本采集的时候用来制作样本,程序可以copy下来直接用
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std ;
using namespace cv;

Mat srcImage,dstImage,copy_Image,temp_Image;
String Picture_Name  ;
void on_mouse(int event,int x,int y,int flags,void *ustc)//event鼠标事件代号,x,y鼠标坐标,flags拖拽和键盘操作的代号
{
static Point pre_pt = (-1,-1);//初始坐标
static Point cur_pt = (-1,-1);//实时坐标
char temp[16];
if (event == CV_EVENT_LBUTTONDOWN)//左键按下,读取初始坐标,并在图像上该点处划圆
{
srcImage.copyTo(copy_Image);//将原始图片复制到copy_Image中
sprintf(temp,"(%d,%d)",x,y); // 把(x,y)坐标写到 temp 中
pre_pt = Point(x,y);
putText(copy_Image,temp,pre_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255),1,8);//在窗口上显示坐标
circle(copy_Image,pre_pt,2,Scalar(255,0,0,0),CV_FILLED,CV_AA,0);//划圆
imshow("原始图像",copy_Image);
}
else if (event == CV_EVENT_MOUSEMOVE && !(flags & CV_EVENT_FLAG_LBUTTON))//左键没有按下的情况下鼠标移动的处理函数
{
copy_Image.copyTo(temp_Image);//将copy_Image复制到临时图像temp_Image上,用于显示实时坐标
sprintf(temp,"(%d,%d)",x,y);
cur_pt = Point(x,y);
putText(temp_Image,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));//只是实时显示鼠标移动的坐标
imshow("原始图像",temp_Image);
}
else if (event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))//左键按下时,鼠标移动,则在图像上划矩形
{
copy_Image.copyTo(temp_Image);
sprintf(temp,"(%d,%d)",x,y);
cur_pt = Point(x,y);
putText(temp_Image,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));  //显示实时坐标
rectangle(temp_Image,pre_pt,cur_pt,Scalar(0,255,0,0),1,8,0);//在临时图像上实时显示鼠标拖动时形成的矩形
imshow("原始图像",temp_Image);
}
else if (event == CV_EVENT_LBUTTONUP)//左键松开,将在图像上划矩形
{
srcImage.copyTo(copy_Image);
sprintf(temp,"(%d,%d)",x,y);
cur_pt = Point(x,y);
putText(copy_Image,temp,cur_pt,FONT_HERSHEY_SIMPLEX,0.5,Scalar(0,0,0,255));  //显示实时坐标
circle(copy_Image,pre_pt,2,Scalar(255,0,0,0),CV_FILLED,CV_AA,0);
rectangle(copy_Image,pre_pt,cur_pt,Scalar(0,255,0,0),1,8,0);//根据初始点和结束点,将矩形画到img上
imshow("原始图像",copy_Image);
copy_Image.copyTo(temp_Image);
//截取矩形包围的图像,并保存到dst中
int width = abs(pre_pt.x - cur_pt.x);  // 取起始点与实时点的差的绝对值为矩形宽
int height = abs(pre_pt.y - cur_pt.y);
if (width == 0 || height == 0)
{
printf("width == 0 || height == 0");
return;
}
dstImage = srcImage(Rect(min(cur_pt.x,pre_pt.x),min(cur_pt.y,pre_pt.y),width,height));
namedWindow("截图");
imshow("截图",dstImage);
waitKey (0);
cout <<"#################是否保存图片,保存请按 q!"<<endl;  //决定是否保存
char c = waitKey (0);  // 读取按键信息
if (c == 'q')          //  按下q 保存图片
{
cout << "请输入要保存的图片名称: ";    // 保存记得  名字+图片类型  例:头部样本.jpg
cin>>Picture_Name;
imwrite (Picture_Name,dstImage);
String Name=Picture_Name.substr(0,Picture_Name.length()-4);   // 图片保存的名字 去掉了.jpg
cout <<"图片保存完毕,可以在工程目录下查看名为:"<<Name<<" 的图片"<<endl;
imshow (Name, dstImage);
waitKey (0);
//  保存一幅图之后可继续 在原图上用鼠标划取样本继续保存,所以说一幅图可以划取多个样本图片保存
}
else
cout <<"未对选取图像进行保存"<<endl;
waitKey (0);
}
}

void main()
{
srcImage = imread("1.jpg");  //读取图片
srcImage.copyTo(copy_Image);  // 原图片图片保存
namedWindow("原始图像");//定义一个窗口
imshow("原始图像",copy_Image);
setMouseCallback("原始图像",on_mouse,0);//调用回调函数
waitKey (0);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息