您的位置:首页 > 其它

图像截取

2015-11-09 18:13 288 查看
http://blog.csdn.net/wuxiaoyao12/article/details/7305865

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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: