有时候,我们只对一幅图像中的部分区域感兴趣,而原图像又十分大,如果带着非感兴趣区域一次处理,就会对程序的内存造成负担,因此我们希望从原始图像中截取部分图像后再进行处理。我们将这个区域称作感兴趣区域(Region of Interest,ROI)。
从原图中截取部分内容,可以用Rect数据结构标记,也可以用Range数据结构标记:
typedef Rect2i Rect;
typedef Rect_<int> Rect2i;
template<typename _Tp> class Rect_
{
public:
// ...
_Tp x; //!< x coordinate of the top-left corner
_Tp y; //!< y coordinate of the top-left corner
_Tp width; //!< width of the rectangle
_Tp height; //!< height of the rectangle
};
img(Rect(p.x, p.y, width, height))
class CV_EXPORTS Range
{
public:
Range();
Range(int _start, int _end);
int size() const;
bool empty() const;
static Range all();
int start, end;
};
// 定义开始和结束范围,可以是行的开始和结束范围,也可以是列的开始和结束范围
img(Range(rows_start, rows_end), Range(cols_start, cols_end));
深拷贝函数copyTo:
void cv::Mat::copyTo( OutputArray m ) const;
void cv::Mat::copyTo( OutputArray m, InputArray mask ) const;
void cv::copyTo(InputArray src, OutputArray dst, InputArray mask);
#include
#include // debug no log
#include
using namespace cv;
using namespace std;
int main()
{
cout << "OpenCV Version: " << CV_VERSION << endl;
utils::logging::setLogLevel(utils::logging::LOG_LEVEL_SILENT);
Mat img = imread("lena.png");
Mat noobcv = imread("noobcv.jpg");
if (img.empty() || noobcv.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat ROI1, ROI2, ROI2_copy, mask, img2, img_copy, img_copy2;
resize(noobcv, mask, Size(200, 200));
img2 = img; //浅拷贝
//深拷贝的两种方式
img.copyTo(img_copy2);
copyTo(img, img_copy, img);
//两种在图中截取ROI区域的方式
Rect rect(206, 206, 200, 200); //定义ROI区域
ROI1 = img(rect); //截图
ROI2 = img(Range(300, 500), Range(300, 500)); //第二种截图方式
img(Range(300, 500), Range(300, 500)).copyTo(ROI2_copy); //深拷贝
mask.copyTo(ROI1); //在图像中加入部分图像
imshow("加入noobcv后图像", img);
imshow("ROI对ROI2的影响", ROI2);
imshow("深拷贝的ROI2_copy", ROI2_copy);
circle(img, Point(300, 300), 20, Scalar(0, 0, 255), -1); //绘制一个圆形
imshow("浅拷贝的img2", img2);
imshow("深拷贝的img_copy", img_copy);
imshow("深拷贝的img_copy2", img_copy2);
imshow("画圆对ROI1的影响", ROI1);
waitKey(0);
return 0;
}