图像截取
来源:互联网 发布:36 1十分抱歉您的网络 编辑:程序博客网 时间:2024/05/17 00:59
http://blog.csdn.net/wuxiaoyao12/article/details/7305865
opencv提取图像的缺陷并用最小矩形框出来
http://blog.csdn.net/s12244315/article/details/48177203
看代码:
- 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
代码如下:
- // 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;
- }
上述代码修改为:
- // 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完成三个部分:
场景背景、动态物体、提取车辆。
代码如下:
- // 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;
- }
- 图像截取
- AWT 截取屏幕图像
- c# 图像截取
- 图像的部分截取
- Cocos2d 截取屏幕图像。
- OpenCv截取图像
- Java 图像截取 缩放
- matlab截取图像
- opencv图像反转/截取
- 图像截取c代码
- canvas-图像截取
- Selenium-如何截取图像
- opencv 鼠标截取图像
- matlab截取图像一部分
- 利用MFC截取对话框图像或者截取全屏图像
- 图像截取的后台处理
- 图像截取的前台页面
- opencv如何截取子图像
- phonegap创建项目错误
- va_list的几个宏操作
- 第六周项目4 后缀表达式
- 变量声明和定义的深入理解
- 第11周实践项目1验证算法-哈夫曼编码的算法验证
- 图像截取
- 大家好,写这些博客以记录我的考研学习时光!
- 项目应用中的卡尔曼滤波
- 黑马程序员——枚举和动态代理
- ajax跨域获取json
- DOCTYPE声明作用及用法详解
- IOS XCode6.4 安装报错
- 第十周项目--【计算二叉树节点个数】
- AFN上传图片