图像截取
2015-11-09 18:13
288 查看
http://blog.csdn.net/wuxiaoyao12/article/details/7305865
看代码:
[cpp]
view plaincopy
IplImage *g = cvLoadImage("C:\\Users\\Administrator\\Desktop\\21.jpg");
IplImage* src = cvCreateImage(cvGetSize(g), IPL_DEPTH_8U, 1);
//转化为单通道黑白照片
CvScalar pixel1;
double temp;
for (int i = 0; i < g->height - 1; ++i)
{
for (int j = 0; j < g->width - 1; ++j)
{
pixel1 = cvGet2D(g, i, j);
temp = 0.11*pixel1.val[0] + 0.59*pixel1.val[1] + 0.30*pixel1.val[2];
cvSet2D(src, i, j, temp);
}
}
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvNamedWindow("image0", 1);
cvShowImage("image0", src);
int hei = src->height;
int wid = src->width;
uchar *data = (uchar*)src->imageData;
int widstep = src->widthStep;
int channel = src->nChannels;
IplImage *dst = cvCreateImage(cvSize(wid, hei), IPL_DEPTH_8U, 3);
// invert the image
for (int i = 0; i<hei; i++)
{
for (int j = 0; j<wid; j++)
{
if (data[i*widstep + j*channel]>160)
{
data[i*widstep + j*channel] = 255;
}
else
{
data[i*widstep + j*channel] = 0;
}
}
}
cvNamedWindow("image", 0);
cvShowImage("image", src);
printf("图像的高为:%d,宽为:%d\n\n", hei, wid);
cvCvtColor(src, dst, CV_GRAY2BGR);
cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
for (; contour != 0; contour = contour->h_next)
{
CvBox2D rect = cvMinAreaRect2(contour, storage);
double area = rect.size.height* rect.size.width;
if (area < 1000)continue;
CvPoint2D32f rect_pts0[4];
cvBoxPoints(rect, rect_pts0);
int npts = 4, k = 0;
int aaa = 0, bbb = 0;
CvPoint rect_pts[4], *pt = rect_pts;
printf("连通区域最小外接矩形顶点坐标分别为:\n");
for (int i = 0; i<4; i++)
{
rect_pts[i] = cvPointFrom32f(rect_pts0[i]);
printf("%d %d\n", rect_pts[i].x, rect_pts[i].y);
aaa = (int)sqrt((pow((rect_pts[0].x - rect_pts[1].x), 2) + pow((rect_pts[0].y
- rect_pts[1].y), 2)));
bbb = (int)sqrt((pow((rect_pts[0].x - rect_pts[3].x), 2) + pow((rect_pts[0].
y - rect_pts[3].y), 2)));
if (aaa<bbb)
{
k = aaa;
aaa = bbb;
bbb = k;
}
}
printf("最小外接矩形的长为:%d宽为:%d。\n\n", aaa, bbb);
cvPolyLine(g, &pt, &npts, 1, 1, CV_RGB(255, 0, 0), 1);
}
cvNamedWindow("image1", 1);
cvShowImage("image1", g);
cvNamedWindow("image", 1);
cvShowImage("image", src);
cvWaitKey(0);
cvDestroyWindow("image");
cvDestroyWindow("image1");
cvReleaseImage(&src);
cvReleaseImage(&g);
效果如图:
Opencv中的ROI介绍
http://www.opencvchina.com/thread-228-1-1.html
ROI(Region of Interest)是指图像中的一个矩形区域,可能你后续的程序需要单独处理这一个小区域,如图所示
如上图所示,就是ROI的一个例子,如果你对图像设置了ROI,那么,Opencv的大多数函数只在该ROI区域内运算(只处理该ROI区域),如果没设ROI的话,就会出来整幅图像。
ROI非常有用,例如我们想把图像中的人脸扣出来,进行人脸识别。需要注意的时候,ROI一定在图像内部,而不能超出图像的范围。
对图像设定ROI的函数是:
cvSetImageROI(IplImage* src,CvRect rect);
src表示的是源图像,rect只的是ROI区域。
如果要取消ROI区域,那么使用函数:
cvResetImageROI(IplImage* src);
这个函数,就把src上的ROI区域取消掉。
下面举几个例子:
例子1:
从一幅大图像中,取出一小块图像并保存这一个小块图像。
代码如下:
/* 读取大图像 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1);
/* 设置图像的ROI区域
注意ROI区域不要越界,必须在大图像的内部 */
cvSetImageROI(img1, cvRect(10, 15, 150, 250));
/* 为小图像分配内存空间
cvGetSize(img1)返回的是一个CvSize结构体,意思就是返回了图像img1的宽度和高度,由于
img已经设置了ROI,所以cvGetSize函数对ROI区域有效,所以,返回的是ROI区域的宽度和高度 */
IplImage *img2 = cvCreateImage(cvGetSize(img1),
img1->depth,
img1->nChannels);
/* 把img1的ROI区域拷贝到img2*/
cvCopy(img1, img2, NULL);
/* 取消img1上的ROI区域 */
cvResetImageROI(img1);
例子2:
两幅不同大小的图像相加
/* 加载图像
注意,这两幅图像有不同的宽度和高度 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1); /* 大图像 */
IplImage *img2 = cvLoadImage("fifi.jpg", 1); /* 较小的图像*/
/* 定义ROI区域的坐标*/
CvRect rect = cvRect(25, 25, img2->width, img2->height);
/* 对图像img1设置ROI1区域 */
cvSetImageROI(img1, rect);
/* 两幅图像相加
注意,通过对img1设置ROI区域后,两幅图像,其实有相同的宽度和高度了。 */
cvAdd(img1, img2, img1, NULL);
/* 取消感兴趣区域,即ROI区域*/
cvResetImageROI(img1);
例子3:在一个特定区域进行模板匹配 (关于模板匹配的完整代码下载)
IplImage *src = cvLoadImage("myphoto.jpg", 1);
IplImage *template = cvLoadImage("eye.jpg", 1);
CvRect rect = cvRect(25, 25, 120, 120);
//设置ROI区域
cvSetImageROI(src, rect);
IplImage *result = cvCreateImage(cvSize(rect.width - tpl->width + 1,
rect.height - tpl->height + 1),
IPL_DEPTH_32F, 1);
/* 进行模板匹配 */
cvMatchTemplate(src, template, result, CV_TM_SQDIFF);
/* 查找最匹配的坐标 */
CvPoint minlocation, maxlocation;
double minvalue, maxvalue;
cvMinMaxLoc(result, &minvalue, &maxvalue, &minlocation, &maxlocation, 0);
/* 在源图像上画出矩形*/
cvRectangle(src,
cvPoint(minlocation.x, minlocationc.y),
cvPoint(minlocation.x + template->width, minlocationc.y + template->height),
CV_RGB(255, 0, 0), 1, 0, 0 );
cvResetImageROI(src);
在上面的例子中,先定义ROI区域,再进行模板匹配,这样会加快匹配的速度,因为,只在ROI区域进行模板匹配运算。
例子4:ROI区域像素值的访问
可以想把ROI区域拷贝到一幅新的图像中,然后再访问其像素值
/* 假设已经有了一幅 8-bit 3通道图像*/
/* ROI的坐标*/
CvRect rect = cvRect(10, 20, 50, 60);
/* ROI区域的子图像 */
IplImage* subimg;
/* 设置ROI区域 */
cvSetImageROI(img, rect);
//ROI区域拷贝
cvCopy(img, subimg, NULL);
//释放ROI区域
cvResetImageROI(img);
/* 然后,就可以对subimg进行访问,其实就是访问ROI区域 */
或者可以通过ROI的左边信息进行访问
/* ROI区域的坐标 */
CvRect rect = cvRect(10, 20, 50, 60);
//设置ROI区域
cvSetImageROI(img, rect);
/* 假设,把整个ROI区域赋值为0 */
for (i = rect.y; i < (rect.y + rect.height); i++) {
for (j = rect.x; j < (rect.x + rect.width); j++) {
((uchar*)(img->imageData + i * img->widthStep))[j*3] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+1] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+2] = 0;
}
}
cvResetImageROI(img);
edited by
www.opencvchina.com
opencv抠图
http://blog.csdn.net/cv_yuippe/article/details/13035063
代码如下:
[cpp]
view plaincopy
// opencv_drawroi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <OpenCV245.h>
using namespace std;
using namespace cv;
CvPoint prev_pt = {-1, -1};
Mat img;
Mat img_mask;
Mat dst;
void on_mouse(int event, int x, int y, int flags, void* )
{
if(!img.data)
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;
}
line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线
line(img, prev_pt, pt, Scalar::all(255),2,8,0); //原图上划线
prev_pt = pt;
imshow("image", img);
}
if (event == CV_EVENT_RBUTTONUP)
{
floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板
imshow("img_mask", img_mask);
waitKey(0);
img.copyTo(dst,img_mask);
imshow("dst", dst);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat image = imread("C:\\Users\\sony\\Desktop\\111.png");
image.copyTo(img);
//将模板设置成白色
inpainted_mask.create(img.rows, img.cols, CV_8U);
inpainted_mask.setTo(Scalar(255));
//显示原图
imshow("image",img);
//显示模板原图
imshow("watershed transform", img_mask);
//鼠标回调函数
cvSetMouseCallback("image",on_mouse,0);
waitKey(0);
return 0;
}
上述代码修改为:
[cpp]
view plaincopy
// opencv_drawroi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <OpenCV245.h>
using namespace std;
using namespace cv;
CvPoint prev_pt = {-1, -1};
Mat img;
Mat img_mask;
Mat dst;
void on_mouse(int event, int x, int y, int flags, void* )
{
if(!img.data)
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;
}
line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线
line(img, prev_pt, pt, Scalar::all(255),2,8,0); //原图上划线
prev_pt = pt;
imshow("image", img);
}
if (event == CV_EVENT_RBUTTONUP)
{
floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板
/*imshow("img_mask", img_mask);*/
img.copyTo(dst,img_mask);
imshow("dst", dst);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat image = imread("C:\\Users\\zj\\Desktop\\111.png");
image.copyTo(img);
//将模板设置成白色
img_mask.create(img.rows, img.cols, CV_8U);
img_mask.setTo(Scalar(255));
//显示原图
imshow("image",img);
////显示模板原图
//imshow("watershed transform", img_mask);
//鼠标回调函数
cvSetMouseCallback("image",on_mouse,0);
waitKey(0);
return 0;
}
结果如下:
版权声明:本文为博主原创文章,未经博主允许不得转载。
框出动态特定物体
http://blog.csdn.net/cv_yuippe/article/details/13508429
完成三个部分:
场景背景、动态物体、提取车辆。
代码如下:
[cpp]
view plaincopy
// opencv_try.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <opencv245.h>
using namespace std;
using namespace cv;
Mat paintRect(Mat &src, Rect &rect)
{
float LTopX = static_cast<float>(rect.x);
float LTopY = static_cast<float>(rect.y);
float RBtmX = static_cast<float>(rect.x + rect.width - 1);
float RBtmY = static_cast<float>(rect.y + rect.height - 1);
Point LTopPonit(LTopX, LTopY);
Point RBtmPoint(RBtmX, RBtmY);
rectangle( src, LTopPonit, RBtmPoint, Scalar(0, 0, 255), 1, 8);
return src;
}
void imgProc(Mat &image, vector<Rect> &vecRect)
{
for (auto it = vecRect.begin();it != vecRect.end(); ++it)
{
image = paintRect(image, *it);
}
}
vector<Rect> returnRect(Mat &src )
{
Mat img;
src.copyTo(img);
/*cvtColor(src,img,CV_GRAY2BGR);
cvtColor(img,img,CV_RGB2GRAY);*/
vector<Rect> rects;
int area;
Rect rect;
/*src.copyTo(img);*/
int nRows = img.rows;
int nCols = img.cols;
for (int j = 0; j < nRows; ++j)
{
uchar* p =img.ptr<uchar>(j);
for (int i = 0; i < nCols; ++i)
{
if (p[i] < 250)
{
p[i] = 0;
}
}
}
/*erode(img,img,Mat(),Point(-1,-1),3);*/
dilate(img,img,Mat(),Point(-1,-1),4);
for (int i=0;i<nRows ;i++)
for(int j=0;j<nCols ;j++)
{
if(img.at<uchar>(i,j) == 255)
{
area = floodFill(img, Point(j,i),Scalar::all(0),&rect);//返回面积和矩形坐标
if (area > 3000)
{
rects.push_back(rect);
}
}
}
return rects;
}
int _tmain(int argc, _TCHAR* argv[])
{
string videoFile = "C:\\Users\\sony\\Desktop\\video\\停车场出入口.flv";
VideoCapture capture;
capture.open(videoFile);
if (!capture.isOpened())
{
cout << "read video failure "<<endl;
return -1;
}
BackgroundSubtractorMOG2 mog;
Mat foreground;
Mat background;
Mat moveobject;
Mat srcproc;
vector<Rect> rectVec;
Mat frame;
long frameNo = 0;
while (capture.read(frame))
{
++frameNo;
cout<<frameNo<<endl;
mog(frame, foreground, 0.001);
//腐蚀
erode(foreground, foreground, Mat());
//膨胀
dilate(foreground,foreground,Mat());
mog.getBackgroundImage(background);
rectVec = returnRect(foreground);
imgProc(frame, rectVec);
imshow("foreground", foreground);
imshow("background", background);
imshow("video", frame);
if (waitKey(25) == 99 )
{
imwrite("C:\\Users\\sony\\Desktop\\forground.jpg", foreground);
imwrite("C:\\Users\\sony\\Desktop\\src.jpg", frame);
}
if (waitKey(25) == 97)
{
break;
}
rectVec.clear();
}
return 0;
}
opencv提取图像的缺陷并用最小矩形框出来
/article/9116828.html看代码:
[cpp]
view plaincopy
IplImage *g = cvLoadImage("C:\\Users\\Administrator\\Desktop\\21.jpg");
IplImage* src = cvCreateImage(cvGetSize(g), IPL_DEPTH_8U, 1);
//转化为单通道黑白照片
CvScalar pixel1;
double temp;
for (int i = 0; i < g->height - 1; ++i)
{
for (int j = 0; j < g->width - 1; ++j)
{
pixel1 = cvGet2D(g, i, j);
temp = 0.11*pixel1.val[0] + 0.59*pixel1.val[1] + 0.30*pixel1.val[2];
cvSet2D(src, i, j, temp);
}
}
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* contour = 0;
cvNamedWindow("image0", 1);
cvShowImage("image0", src);
int hei = src->height;
int wid = src->width;
uchar *data = (uchar*)src->imageData;
int widstep = src->widthStep;
int channel = src->nChannels;
IplImage *dst = cvCreateImage(cvSize(wid, hei), IPL_DEPTH_8U, 3);
// invert the image
for (int i = 0; i<hei; i++)
{
for (int j = 0; j<wid; j++)
{
if (data[i*widstep + j*channel]>160)
{
data[i*widstep + j*channel] = 255;
}
else
{
data[i*widstep + j*channel] = 0;
}
}
}
cvNamedWindow("image", 0);
cvShowImage("image", src);
printf("图像的高为:%d,宽为:%d\n\n", hei, wid);
cvCvtColor(src, dst, CV_GRAY2BGR);
cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);
for (; contour != 0; contour = contour->h_next)
{
CvBox2D rect = cvMinAreaRect2(contour, storage);
double area = rect.size.height* rect.size.width;
if (area < 1000)continue;
CvPoint2D32f rect_pts0[4];
cvBoxPoints(rect, rect_pts0);
int npts = 4, k = 0;
int aaa = 0, bbb = 0;
CvPoint rect_pts[4], *pt = rect_pts;
printf("连通区域最小外接矩形顶点坐标分别为:\n");
for (int i = 0; i<4; i++)
{
rect_pts[i] = cvPointFrom32f(rect_pts0[i]);
printf("%d %d\n", rect_pts[i].x, rect_pts[i].y);
aaa = (int)sqrt((pow((rect_pts[0].x - rect_pts[1].x), 2) + pow((rect_pts[0].y
- rect_pts[1].y), 2)));
bbb = (int)sqrt((pow((rect_pts[0].x - rect_pts[3].x), 2) + pow((rect_pts[0].
y - rect_pts[3].y), 2)));
if (aaa<bbb)
{
k = aaa;
aaa = bbb;
bbb = k;
}
}
printf("最小外接矩形的长为:%d宽为:%d。\n\n", aaa, bbb);
cvPolyLine(g, &pt, &npts, 1, 1, CV_RGB(255, 0, 0), 1);
}
cvNamedWindow("image1", 1);
cvShowImage("image1", g);
cvNamedWindow("image", 1);
cvShowImage("image", src);
cvWaitKey(0);
cvDestroyWindow("image");
cvDestroyWindow("image1");
cvReleaseImage(&src);
cvReleaseImage(&g);
效果如图:
Opencv中的ROI介绍
http://www.opencvchina.com/thread-228-1-1.html
ROI(Region of Interest)是指图像中的一个矩形区域,可能你后续的程序需要单独处理这一个小区域,如图所示
如上图所示,就是ROI的一个例子,如果你对图像设置了ROI,那么,Opencv的大多数函数只在该ROI区域内运算(只处理该ROI区域),如果没设ROI的话,就会出来整幅图像。
ROI非常有用,例如我们想把图像中的人脸扣出来,进行人脸识别。需要注意的时候,ROI一定在图像内部,而不能超出图像的范围。
对图像设定ROI的函数是:
cvSetImageROI(IplImage* src,CvRect rect);
src表示的是源图像,rect只的是ROI区域。
如果要取消ROI区域,那么使用函数:
cvResetImageROI(IplImage* src);
这个函数,就把src上的ROI区域取消掉。
下面举几个例子:
例子1:
从一幅大图像中,取出一小块图像并保存这一个小块图像。
代码如下:
/* 读取大图像 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1);
/* 设置图像的ROI区域
注意ROI区域不要越界,必须在大图像的内部 */
cvSetImageROI(img1, cvRect(10, 15, 150, 250));
/* 为小图像分配内存空间
cvGetSize(img1)返回的是一个CvSize结构体,意思就是返回了图像img1的宽度和高度,由于
img已经设置了ROI,所以cvGetSize函数对ROI区域有效,所以,返回的是ROI区域的宽度和高度 */
IplImage *img2 = cvCreateImage(cvGetSize(img1),
img1->depth,
img1->nChannels);
/* 把img1的ROI区域拷贝到img2*/
cvCopy(img1, img2, NULL);
/* 取消img1上的ROI区域 */
cvResetImageROI(img1);
例子2:
两幅不同大小的图像相加
/* 加载图像
注意,这两幅图像有不同的宽度和高度 */
IplImage *img1 = cvLoadImage("elvita.jpg", 1); /* 大图像 */
IplImage *img2 = cvLoadImage("fifi.jpg", 1); /* 较小的图像*/
/* 定义ROI区域的坐标*/
CvRect rect = cvRect(25, 25, img2->width, img2->height);
/* 对图像img1设置ROI1区域 */
cvSetImageROI(img1, rect);
/* 两幅图像相加
注意,通过对img1设置ROI区域后,两幅图像,其实有相同的宽度和高度了。 */
cvAdd(img1, img2, img1, NULL);
/* 取消感兴趣区域,即ROI区域*/
cvResetImageROI(img1);
例子3:在一个特定区域进行模板匹配 (关于模板匹配的完整代码下载)
IplImage *src = cvLoadImage("myphoto.jpg", 1);
IplImage *template = cvLoadImage("eye.jpg", 1);
CvRect rect = cvRect(25, 25, 120, 120);
//设置ROI区域
cvSetImageROI(src, rect);
IplImage *result = cvCreateImage(cvSize(rect.width - tpl->width + 1,
rect.height - tpl->height + 1),
IPL_DEPTH_32F, 1);
/* 进行模板匹配 */
cvMatchTemplate(src, template, result, CV_TM_SQDIFF);
/* 查找最匹配的坐标 */
CvPoint minlocation, maxlocation;
double minvalue, maxvalue;
cvMinMaxLoc(result, &minvalue, &maxvalue, &minlocation, &maxlocation, 0);
/* 在源图像上画出矩形*/
cvRectangle(src,
cvPoint(minlocation.x, minlocationc.y),
cvPoint(minlocation.x + template->width, minlocationc.y + template->height),
CV_RGB(255, 0, 0), 1, 0, 0 );
cvResetImageROI(src);
在上面的例子中,先定义ROI区域,再进行模板匹配,这样会加快匹配的速度,因为,只在ROI区域进行模板匹配运算。
例子4:ROI区域像素值的访问
可以想把ROI区域拷贝到一幅新的图像中,然后再访问其像素值
/* 假设已经有了一幅 8-bit 3通道图像*/
/* ROI的坐标*/
CvRect rect = cvRect(10, 20, 50, 60);
/* ROI区域的子图像 */
IplImage* subimg;
/* 设置ROI区域 */
cvSetImageROI(img, rect);
//ROI区域拷贝
cvCopy(img, subimg, NULL);
//释放ROI区域
cvResetImageROI(img);
/* 然后,就可以对subimg进行访问,其实就是访问ROI区域 */
或者可以通过ROI的左边信息进行访问
/* ROI区域的坐标 */
CvRect rect = cvRect(10, 20, 50, 60);
//设置ROI区域
cvSetImageROI(img, rect);
/* 假设,把整个ROI区域赋值为0 */
for (i = rect.y; i < (rect.y + rect.height); i++) {
for (j = rect.x; j < (rect.x + rect.width); j++) {
((uchar*)(img->imageData + i * img->widthStep))[j*3] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+1] = 0;
((uchar*)(img->imageData + i * img->widthStep))[j*3+2] = 0;
}
}
cvResetImageROI(img);
edited by
www.opencvchina.com
opencv抠图
http://blog.csdn.net/cv_yuippe/article/details/13035063代码如下:
[cpp]
view plaincopy
// opencv_drawroi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <OpenCV245.h>
using namespace std;
using namespace cv;
CvPoint prev_pt = {-1, -1};
Mat img;
Mat img_mask;
Mat dst;
void on_mouse(int event, int x, int y, int flags, void* )
{
if(!img.data)
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;
}
line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线
line(img, prev_pt, pt, Scalar::all(255),2,8,0); //原图上划线
prev_pt = pt;
imshow("image", img);
}
if (event == CV_EVENT_RBUTTONUP)
{
floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板
imshow("img_mask", img_mask);
waitKey(0);
img.copyTo(dst,img_mask);
imshow("dst", dst);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat image = imread("C:\\Users\\sony\\Desktop\\111.png");
image.copyTo(img);
//将模板设置成白色
inpainted_mask.create(img.rows, img.cols, CV_8U);
inpainted_mask.setTo(Scalar(255));
//显示原图
imshow("image",img);
//显示模板原图
imshow("watershed transform", img_mask);
//鼠标回调函数
cvSetMouseCallback("image",on_mouse,0);
waitKey(0);
return 0;
}
上述代码修改为:
[cpp]
view plaincopy
// opencv_drawroi.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <OpenCV245.h>
using namespace std;
using namespace cv;
CvPoint prev_pt = {-1, -1};
Mat img;
Mat img_mask;
Mat dst;
void on_mouse(int event, int x, int y, int flags, void* )
{
if(!img.data)
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;
}
line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线
line(img, prev_pt, pt, Scalar::all(255),2,8,0); //原图上划线
prev_pt = pt;
imshow("image", img);
}
if (event == CV_EVENT_RBUTTONUP)
{
floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板
/*imshow("img_mask", img_mask);*/
img.copyTo(dst,img_mask);
imshow("dst", dst);
}
}
int _tmain(int argc, _TCHAR* argv[])
{
Mat image = imread("C:\\Users\\zj\\Desktop\\111.png");
image.copyTo(img);
//将模板设置成白色
img_mask.create(img.rows, img.cols, CV_8U);
img_mask.setTo(Scalar(255));
//显示原图
imshow("image",img);
////显示模板原图
//imshow("watershed transform", img_mask);
//鼠标回调函数
cvSetMouseCallback("image",on_mouse,0);
waitKey(0);
return 0;
}
结果如下:
版权声明:本文为博主原创文章,未经博主允许不得转载。
框出动态特定物体
http://blog.csdn.net/cv_yuippe/article/details/13508429完成三个部分:
场景背景、动态物体、提取车辆。
代码如下:
[cpp]
view plaincopy
// opencv_try.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <string>
#include <opencv245.h>
using namespace std;
using namespace cv;
Mat paintRect(Mat &src, Rect &rect)
{
float LTopX = static_cast<float>(rect.x);
float LTopY = static_cast<float>(rect.y);
float RBtmX = static_cast<float>(rect.x + rect.width - 1);
float RBtmY = static_cast<float>(rect.y + rect.height - 1);
Point LTopPonit(LTopX, LTopY);
Point RBtmPoint(RBtmX, RBtmY);
rectangle( src, LTopPonit, RBtmPoint, Scalar(0, 0, 255), 1, 8);
return src;
}
void imgProc(Mat &image, vector<Rect> &vecRect)
{
for (auto it = vecRect.begin();it != vecRect.end(); ++it)
{
image = paintRect(image, *it);
}
}
vector<Rect> returnRect(Mat &src )
{
Mat img;
src.copyTo(img);
/*cvtColor(src,img,CV_GRAY2BGR);
cvtColor(img,img,CV_RGB2GRAY);*/
vector<Rect> rects;
int area;
Rect rect;
/*src.copyTo(img);*/
int nRows = img.rows;
int nCols = img.cols;
for (int j = 0; j < nRows; ++j)
{
uchar* p =img.ptr<uchar>(j);
for (int i = 0; i < nCols; ++i)
{
if (p[i] < 250)
{
p[i] = 0;
}
}
}
/*erode(img,img,Mat(),Point(-1,-1),3);*/
dilate(img,img,Mat(),Point(-1,-1),4);
for (int i=0;i<nRows ;i++)
for(int j=0;j<nCols ;j++)
{
if(img.at<uchar>(i,j) == 255)
{
area = floodFill(img, Point(j,i),Scalar::all(0),&rect);//返回面积和矩形坐标
if (area > 3000)
{
rects.push_back(rect);
}
}
}
return rects;
}
int _tmain(int argc, _TCHAR* argv[])
{
string videoFile = "C:\\Users\\sony\\Desktop\\video\\停车场出入口.flv";
VideoCapture capture;
capture.open(videoFile);
if (!capture.isOpened())
{
cout << "read video failure "<<endl;
return -1;
}
BackgroundSubtractorMOG2 mog;
Mat foreground;
Mat background;
Mat moveobject;
Mat srcproc;
vector<Rect> rectVec;
Mat frame;
long frameNo = 0;
while (capture.read(frame))
{
++frameNo;
cout<<frameNo<<endl;
mog(frame, foreground, 0.001);
//腐蚀
erode(foreground, foreground, Mat());
//膨胀
dilate(foreground,foreground,Mat());
mog.getBackgroundImage(background);
rectVec = returnRect(foreground);
imgProc(frame, rectVec);
imshow("foreground", foreground);
imshow("background", background);
imshow("video", frame);
if (waitKey(25) == 99 )
{
imwrite("C:\\Users\\sony\\Desktop\\forground.jpg", foreground);
imwrite("C:\\Users\\sony\\Desktop\\src.jpg", frame);
}
if (waitKey(25) == 97)
{
break;
}
rectVec.clear();
}
return 0;
}
相关文章推荐
- android判断当前应用在前台还是后台
- nagios_自定义宏变量隐藏发送邮件账号的敏感信息
- iOS开发网络篇之文件下载、大文件下载、断点下载
- 1103. Integer Factorization
- Java线程synchronized
- 怎么做QQ、微信等消息气泡
- java.lang.OutOfMemoryError: PermGen space错误解决方法 windows
- hdoj 5545 The Battle of Guandu 【差分约束系统 求解多源最短路】
- 第三方评论插件的血与泪
- ora-01652无法通过128(在表空间temp中)
- Codeforces 543A Writing Code 【滚动数组优化dp】
- Android 计算器的开发
- 协议中的属性和类中属性的区别
- ACE简单实现网络聊天(文字)
- 某某面试题
- AngularJS入门实例2——控制器的使用
- MariaDB10.0.21 编译安装 脚本
- 文件上传注意事项
- IC验证平台STE_V2.1实物图和架构图
- 文本挖掘之文本聚类(DBSCAN)