opencv3实现图像裁剪和图像填充(cv::copyMakeBorder)

来源:互联网 发布:start here mac.app 编辑:程序博客网 时间:2024/06/01 08:01

MATLAB中小矩阵赋值到大矩阵的某一区域,很方便实现,换到opencv3.1.0版本下,稍微有些麻烦,把尝试的代码记录如下;

主要包括:

填充边界函数cv::copyMakeBorder(对应opencv2中的cvCopyMakeBorder

降采样cv::resize

可以借用到图像裁剪

注:opencv3中图像和Mat格式不能直接转,使用

    <span></span>src = cvLoadImage(im_path);cv::Mat src0 = cv::cvarrToMat(src);

#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>cv::Mat im_crop0(cv::Mat img, cv::Rect rect){cv::Mat I = cv::Mat::zeros(rect.height, rect.width, 0);// 目标图像// 获取可填充图像int crop_x1 = cv::max(0,rect.x);int crop_y1 = cv::max(0,rect.y);int crop_x2 = cv::min(img.cols - 1, rect.x + rect.width - 1); // 图像范围 0到cols-1, 0到rows-1int crop_y2 = cv::min(img.rows - 1, rect.y + rect.height - 1);cv::Mat roi_img = img(cv::Range(crop_y1,crop_y2 + 1),cv::Range(crop_x1,crop_x2 + 1));// 左包含,右不包含// 如果需要填边int left_x = (- rect.x);int top_y = (- rect.y);int right_x = rect.x + rect.width - img.cols;int down_y = rect.y + rect.height - img.rows;if(top_y > 0 || down_y > 0 || left_x > 0 || right_x > 0){left_x = (left_x>0 ? left_x : 0);right_x = (right_x>0 ? right_x : 0);top_y = (top_y>0 ? top_y : 0);down_y = (down_y>0 ? down_y : 0);cv::copyMakeBorder( roi_img, I, top_y, down_y, left_x, right_x, cv::BORDER_CONSTANT, 0); // 自带填充边界函数,top_y, down_y, left_x, right_x为非负正数// 而且I.cols = roi_img.cols + left_x + right_x, I.rows = roi_img.rows + top_y + down_y}return I;}cv::Mat im_crop(cv::Mat img, cv::Rect rect){cv::Mat I = cv::Mat::zeros(rect.height, rect.width, 0);// 目标图像// 获取可填充图像int crop_x1 = cv::max(0,rect.x);int crop_y1 = cv::max(0,rect.y);int crop_x2 = cv::min(img.cols - 1, rect.x + rect.width - 1); // 图像范围 0到cols-1, 0到rows-1int crop_y2 = cv::min(img.rows - 1, rect.y + rect.height - 1);cv::Mat roi_img = img(cv::Range(crop_y1,crop_y2 + 1),cv::Range(crop_x1,crop_x2 + 1));// 左包含,右不包含// 截取图像在I中位置int x1 = crop_x1 - rect.x;int y1 = crop_y1 - rect.y;int x2 = crop_x2 - rect.x;int y2 = crop_y2 - rect.y;I(cv::Range(y1, y2+1), cv::Range(x1, x2+1)) = I(cv::Range(y1, y2+1), cv::Range(x1, x2+1)) + roi_img;// 此处用加法,虽然I初始设置值全0,但是如果不用加法,直接“=”赋值,结果为0,不是想要的结果return I;}int main(int argc)  {      <span style="white-space:pre"></span>char *im_path = "E:\\1.jpg";<span style="white-space:pre"></span>IplImage* src;        <span style="white-space:pre"></span>src = cvLoadImage(im_path);cv::Mat src0 = cv::cvarrToMat(src);cv::Mat src1;    <span style="white-space:pre"></span>cv::cvtColor(src0, src1, CV_RGB2GRAY);cv::Mat dst2;cv::resize(src1, dst2, cv::Size(), 0.25, 0.5, CV_INTER_LINEAR);// 0.25为列缩小倍数,0.5为行缩小倍数cv::Rect bb(300,-3,100,100);cv::Mat crop_im = im_crop(src1, bb);   <span style="white-space:pre"></span> // 裁剪图像对应该矩形框的区域,越界处填充0// 函数im_crop和im_crop0都可以实现,方法不同   cvNamedWindow( "crop", 0 );  cv::imshow( "crop", crop_im );    <span style="white-space:pre"></span>cvWaitKey(0);     <span style="white-space:pre"></span>cvReleaseImage( &src );     <span style="white-space:pre"></span>cvDestroyAllWindows();   <span style="white-space:pre"></span>return 0;  }


0 0
原创粉丝点击