图像截取

来源:互联网 发布:36 1十分抱歉您的网络 编辑:程序博客网 时间:2024/05/17 00:59

http://blog.csdn.net/wuxiaoyao12/article/details/7305865

opencv提取图像的缺陷并用最小矩形框出来

http://blog.csdn.net/s12244315/article/details/48177203

看代码:

[cpp] view plaincopy
  1. IplImage *g = cvLoadImage("C:\\Users\\Administrator\\Desktop\\21.jpg");  
  2. IplImage* src = cvCreateImage(cvGetSize(g), IPL_DEPTH_8U, 1);  
  3.   
  4. //转化为单通道黑白照片  
  5. CvScalar pixel1;  
  6. double temp;  
  7. for (int i = 0; i < g->height - 1; ++i)  
  8. {  
  9.     for (int j = 0; j < g->width - 1; ++j)  
  10.     {  
  11.         pixel1 = cvGet2D(g, i, j);  
  12.         temp = 0.11*pixel1.val[0] + 0.59*pixel1.val[1] + 0.30*pixel1.val[2];  
  13.         cvSet2D(src, i, j, temp);  
  14.     }  
  15. }  
  16.   
  17. CvMemStorage* storage = cvCreateMemStorage(0);  
  18. CvSeq* contour = 0;  
  19.   
  20. cvNamedWindow("image0", 1);  
  21. cvShowImage("image0", src);  
  22. int   hei = src->height;  
  23. int   wid = src->width;  
  24. uchar *data = (uchar*)src->imageData;  
  25. int widstep = src->widthStep;  
  26. int channel = src->nChannels;  
  27. IplImage *dst = cvCreateImage(cvSize(wid, hei), IPL_DEPTH_8U, 3);  
  28.   
  29.   
  30. // invert the image    
  31. for (int i = 0; i<hei; i++)  
  32. {  
  33.     for (int j = 0; j<wid; j++)  
  34.     {  
  35.         if (data[i*widstep + j*channel]>160)  
  36.         {  
  37.             data[i*widstep + j*channel] = 255;  
  38.         }  
  39.         else  
  40.         {  
  41.             data[i*widstep + j*channel] = 0;  
  42.         }  
  43.     }  
  44. }  
  45.   
  46.   
  47. cvNamedWindow("image", 0);  
  48. cvShowImage("image", src);  
  49. printf("图像的高为:%d,宽为:%d\n\n", hei, wid);  
  50. cvCvtColor(src, dst, CV_GRAY2BGR);  
  51. cvFindContours(src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);  
  52. for (; contour != 0; contour = contour->h_next)  
  53. {  
  54.     CvBox2D rect = cvMinAreaRect2(contour, storage);  
  55.     double area = rect.size.height* rect.size.width;  
  56.     if (area < 1000)continue;  
  57.   
  58.     CvPoint2D32f rect_pts0[4];  
  59.     cvBoxPoints(rect, rect_pts0);  
  60.       
  61.   
  62.     int npts = 4, k = 0;  
  63.     int aaa = 0, bbb = 0;  
  64.     CvPoint rect_pts[4], *pt = rect_pts;  
  65.       
  66.   
  67.     printf("连通区域最小外接矩形顶点坐标分别为:\n");  
  68.     for (int i = 0; i<4; i++)  
  69.     {  
  70.         rect_pts[i] = cvPointFrom32f(rect_pts0[i]);  
  71.         printf("%d %d\n", rect_pts[i].x, rect_pts[i].y);  
  72.         aaa = (int)sqrt((pow((rect_pts[0].x - rect_pts[1].x), 2) + pow((rect_pts[0].y  
  73.             - rect_pts[1].y), 2)));  
  74.         bbb = (int)sqrt((pow((rect_pts[0].x - rect_pts[3].x), 2) + pow((rect_pts[0].  
  75.             y - rect_pts[3].y), 2)));  
  76.         if (aaa<bbb)  
  77.         {  
  78.             k = aaa;  
  79.             aaa = bbb;  
  80.             bbb = k;  
  81.         }  
  82.     }  
  83.     printf("最小外接矩形的长为:%d宽为:%d。\n\n", aaa, bbb);  
  84.     cvPolyLine(g, &pt, &npts, 1, 1, CV_RGB(255, 0, 0), 1);  
  85. }  
  86. cvNamedWindow("image1", 1);  
  87. cvShowImage("image1", g);  
  88. cvNamedWindow("image", 1);  
  89. cvShowImage("image", src);  
  90. cvWaitKey(0);  
  91. cvDestroyWindow("image");  
  92. cvDestroyWindow("image1");  
  93. cvReleaseImage(&src);  
  94. 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在CODE上查看代码片派生到我的代码片
  1. // opencv_drawroi.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <OpenCV245.h>  
  6.   
  7.   
  8. using namespace std;  
  9. using namespace cv;  
  10.   
  11.   
  12.   
  13. CvPoint prev_pt = {-1, -1};  
  14. Mat img;  
  15.   
  16. Mat img_mask;  
  17. Mat dst;  
  18.   
  19.   
  20. void on_mouse(int event, int x, int y, int flags, void* )  
  21. {  
  22.     if(!img.data)  
  23.         return;  
  24.     if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽  
  25.     {  
  26.         prev_pt = cvPoint(-1, -1);  
  27.     }  
  28.     else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键  
  29.     {  
  30.         prev_pt = cvPoint(x,y);  
  31.     }  
  32.     else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽  
  33.     {  
  34.         CvPoint pt = cvPoint(x, y);  
  35.         if ( prev_pt.x < 0)  
  36.         {  
  37.             prev_pt = pt;  
  38.         }  
  39.         line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线  
  40.         line(img, prev_pt, pt, Scalar::all(255),2,8,0);          //原图上划线  
  41.         prev_pt = pt;  
  42.         imshow("image", img);  
  43.           
  44.           
  45.           
  46.           
  47.           
  48.     }  
  49.     if (event == CV_EVENT_RBUTTONUP)  
  50.     {  
  51.           
  52.         floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板  
  53.         imshow("img_mask", img_mask);  
  54.         waitKey(0);  
  55.         img.copyTo(dst,img_mask);  
  56.         imshow("dst", dst);  
  57.           
  58.           
  59.     }  
  60.   
  61. }  
  62.   
  63.   
  64.   
  65. int _tmain(int argc, _TCHAR* argv[])  
  66. {  
  67.       
  68.     Mat image = imread("C:\\Users\\sony\\Desktop\\111.png");  
  69.     image.copyTo(img);  
  70.       
  71.     //将模板设置成白色  
  72.      inpainted_mask.create(img.rows, img.cols, CV_8U);   
  73.      inpainted_mask.setTo(Scalar(255));  
  74.     //显示原图  
  75.     imshow("image",img);  
  76.       
  77.     //显示模板原图  
  78.     imshow("watershed transform", img_mask);  
  79.       
  80.     //鼠标回调函数  
  81.     cvSetMouseCallback("image",on_mouse,0);  
  82.       
  83.   
  84.   
  85.     waitKey(0);  
  86.     return 0;  
  87. }  

上述代码修改为:

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. // opencv_drawroi.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4. #include "stdafx.h"  
  5. #include <OpenCV245.h>  
  6.   
  7.   
  8. using namespace std;  
  9. using namespace cv;  
  10.   
  11.   
  12.   
  13. CvPoint prev_pt = {-1, -1};  
  14. Mat img;  
  15.   
  16. Mat img_mask;  
  17. Mat dst;  
  18.   
  19.   
  20. void on_mouse(int event, int x, int y, int flags, void* )  
  21. {  
  22.     if(!img.data)  
  23.         return;  
  24.     if ( event == CV_EVENT_LBUTTONUP || !(flags & CV_EVENT_FLAG_LBUTTON))  //判断事件为松开鼠标左键或者不是左拖拽  
  25.     {  
  26.         prev_pt = cvPoint(-1, -1);  
  27.     }  
  28.     else if (event == CV_EVENT_LBUTTONDOWN)  //判断为按下左键  
  29.     {  
  30.         prev_pt = cvPoint(x,y);  
  31.     }  
  32.     else if ( event == CV_EVENT_MOUSEMOVE && (flags & CV_EVENT_FLAG_LBUTTON))  //判断移动鼠标并且左拖拽  
  33.     {  
  34.         CvPoint pt = cvPoint(x, y);  
  35.         if ( prev_pt.x < 0)  
  36.         {  
  37.             prev_pt = pt;  
  38.         }  
  39.         line(img_mask, prev_pt, pt, Scalar(0),2,8,0); //模板上划线  
  40.         line(img, prev_pt, pt, Scalar::all(255),2,8,0);          //原图上划线  
  41.         prev_pt = pt;  
  42.         imshow("image", img);  
  43.   
  44.   
  45.   
  46.   
  47.   
  48.     }  
  49.     if (event == CV_EVENT_RBUTTONUP)  
  50.     {  
  51.   
  52.         floodFill(img_mask,Point(x,y),Scalar(0));//填充抠图模板  
  53.         /*imshow("img_mask", img_mask);*/  
  54.         img.copyTo(dst,img_mask);  
  55.         imshow("dst", dst);  
  56.   
  57.   
  58.     }  
  59.   
  60. }  
  61.   
  62.   
  63.   
  64. int _tmain(int argc, _TCHAR* argv[])  
  65. {  
  66.   
  67.     Mat image = imread("C:\\Users\\zj\\Desktop\\111.png");  
  68.     image.copyTo(img);  
  69.   
  70.     //将模板设置成白色  
  71.     img_mask.create(img.rows, img.cols, CV_8U);   
  72.     img_mask.setTo(Scalar(255));  
  73.     //显示原图  
  74.     imshow("image",img);  
  75.       
  76.   
  77.     ////显示模板原图  
  78.     //imshow("watershed transform", img_mask);  
  79.       
  80.     //鼠标回调函数  
  81.     cvSetMouseCallback("image",on_mouse,0);  
  82.   
  83.   
  84.   
  85.     waitKey(0);  
  86.     return 0;  
  87. }  


结果如下:

版权声明:本文为博主原创文章,未经博主允许不得转载。

框出动态特定物体

http://blog.csdn.net/cv_yuippe/article/details/13508429

完成三个部分:

场景背景、动态物体、提取车辆。

代码如下:

[cpp] view plaincopy
  1. // opencv_try.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3.   
  4.   
  5. #include "stdafx.h"  
  6. #include <string>  
  7. #include <opencv245.h>  
  8.   
  9. using namespace std;  
  10. using namespace cv;  
  11.   
  12.   
  13.   
  14. Mat paintRect(Mat &src, Rect &rect)    
  15. {    
  16.     float LTopX = static_cast<float>(rect.x);    
  17.     float LTopY = static_cast<float>(rect.y);    
  18.     float RBtmX = static_cast<float>(rect.x + rect.width - 1);    
  19.     float RBtmY = static_cast<float>(rect.y + rect.height - 1);    
  20.   
  21.     Point LTopPonit(LTopX, LTopY);    
  22.     Point RBtmPoint(RBtmX, RBtmY);    
  23.   
  24.     rectangle( src, LTopPonit, RBtmPoint, Scalar(0, 0, 255), 1, 8);    
  25.   
  26.   
  27.     return src;  
  28. }    
  29.   
  30. void imgProc(Mat &image, vector<Rect> &vecRect)  
  31. {  
  32.     for (auto it = vecRect.begin();it != vecRect.end(); ++it)  
  33.     {  
  34.         image = paintRect(image, *it);  
  35.   
  36.     }  
  37. }  
  38.   
  39. vector<Rect> returnRect(Mat &src )  
  40. {  
  41.       
  42.     Mat img;  
  43.     src.copyTo(img);  
  44.     /*cvtColor(src,img,CV_GRAY2BGR); 
  45.     cvtColor(img,img,CV_RGB2GRAY);*/  
  46.     vector<Rect> rects;  
  47.       
  48.     int area;  
  49.     Rect rect;  
  50.     /*src.copyTo(img);*/  
  51.     int nRows = img.rows;  
  52.     int nCols = img.cols;  
  53.     for (int j = 0; j < nRows; ++j)  
  54.     {  
  55.         uchar* p =img.ptr<uchar>(j);  
  56.         for (int i = 0; i < nCols; ++i)  
  57.         {  
  58.             if (p[i] < 250)  
  59.             {  
  60.                 p[i] = 0;  
  61.             }  
  62.         }  
  63.     }  
  64.   
  65.     /*erode(img,img,Mat(),Point(-1,-1),3);*/  
  66.     dilate(img,img,Mat(),Point(-1,-1),4);  
  67.   
  68.     for (int i=0;i<nRows ;i++)  
  69.         for(int j=0;j<nCols ;j++)  
  70.         {  
  71.             if(img.at<uchar>(i,j) == 255)  
  72.             {  
  73.                 area = floodFill(img, Point(j,i),Scalar::all(0),&rect);//返回面积和矩形坐标  
  74.                 if (area > 3000)  
  75.                 {  
  76.                     rects.push_back(rect);  
  77.                 }  
  78.   
  79.   
  80.             }  
  81.         }  
  82.         return rects;  
  83. }  
  84.   
  85. int _tmain(int argc, _TCHAR* argv[])  
  86. {  
  87.     string videoFile = "C:\\Users\\sony\\Desktop\\video\\停车场出入口.flv";  
  88.   
  89.     VideoCapture capture;  
  90.     capture.open(videoFile);  
  91.   
  92.     if (!capture.isOpened())  
  93.     {  
  94.         cout << "read video failure "<<endl;  
  95.         return -1;  
  96.     }  
  97.   
  98.     BackgroundSubtractorMOG2 mog;  
  99.   
  100.     Mat foreground;  
  101.     Mat background;  
  102.     Mat moveobject;  
  103.     Mat srcproc;  
  104.     vector<Rect> rectVec;  
  105.   
  106.     Mat frame;  
  107.     long frameNo = 0;  
  108.     while (capture.read(frame))  
  109.     {  
  110.         ++frameNo;  
  111.   
  112.         cout<<frameNo<<endl;  
  113.   
  114.         mog(frame, foreground, 0.001);  
  115.   
  116.         //腐蚀  
  117.         erode(foreground, foreground, Mat());  
  118.   
  119.         //膨胀  
  120.         dilate(foreground,foreground,Mat());  
  121.           
  122.   
  123.         mog.getBackgroundImage(background);  
  124.           
  125.           
  126.         rectVec = returnRect(foreground);  
  127.         imgProc(frame, rectVec);  
  128.           
  129.           
  130.           
  131.   
  132.         imshow("foreground", foreground);  
  133.         imshow("background", background);  
  134.         imshow("video", frame);  
  135.   
  136.           
  137.   
  138.         if (waitKey(25) == 99 )  
  139.         {  
  140.             imwrite("C:\\Users\\sony\\Desktop\\forground.jpg", foreground);  
  141.             imwrite("C:\\Users\\sony\\Desktop\\src.jpg", frame);  
  142.   
  143.         }  
  144.         if (waitKey(25) == 97)  
  145.         {  
  146.             break;  
  147.         }  
  148.         rectVec.clear();  
  149.     }  
  150.   
  151.   
  152.     return 0;  
  153. }  



0 0
原创粉丝点击