OpenCV图像裁剪:使用&运算符在OpenCV图像裁剪时进行边界检查

给定ROI的图像裁剪

假设需要按照既定的ROI对图像进行取窗裁剪,用cv::Rect给定ROI区域,裁剪可以按照如下方式:

cpp 复制代码
cv::Mat image = cv::imread("/path/to/image.jpg");
cv::Rect roi = cv::Rect(x, y, width, height);
cv::Mat crop = image(roi);

限制边界

如果roi的坐标超出了图像的合法区域,会引发运行时错误,导致程序崩溃。此时一般要提前进行边界检查和规范,比如这样:

cpp 复制代码
if(roi.x<0) roi.x=0;
if(roi.y<0) roi.y=0;
if(roi.x+roi.width >= image.cols) roi.width = image.cols-roi.x;
if(roi.y+roi.height >= image.rows) roi.heigth = image.rows-roi.y;

这样写代码,看上去不太直观,而且有些冗长,更谈不上优雅或者可读性。

或者这样:

cpp 复制代码
int w = image.cols;
int h = image.rows;

int x0 = std::max<int>(0, roi.tl().x);
int y0 = std::max<int>(0, roi.tl().y);
int x1 = std::min<int>(w, roi.br().x);
int y1 = std::min<int>(h, roi.br().y);

roi = cv::Rect(cv::Point(x0, y0), cv::Point(x1, y1));

稍微增加了些可读性,特别是如果习惯于使用stl的max/min函数进行边界检查。但是仍然冗长,不够优雅。冗长有什么坏处?一般来讲,冗长的代码不易于维护,可读性不会太强。另外以上面这段实现为例,由于反复使用同一变量,仅仅为了对其不同的成员做类似的操作,非常容易导致低级错误。

Operator & : Get Intersection of cv::Rect

这个运算符&比较直观。在C/C++语法中,&属于位运算,是按位与的功能。cv::Rect类型重载了它,可以想象它的功能就是取矩形的相交区域。所以要对图像ROI的cv::Rect进行边界限制,那么将ROI和表示图像区域的Bounding Box求相交区域即可。代码实现如下:

cpp 复制代码
cv::Rect bbox(0, 0, mat.cols, mat.rows);
cv::Rect roi = roi & bbox; // that's all

这样基本上就一句话完成了边界限制。

What's More: verify if rect is inside image

进一步说,如果要检查一个rect是否在图像区域内,不用Operator的话,一般按照以下思路实现:

cpp 复制代码
bool rectIsInside(const cv::Rect& rect, const cv::Mat& image)
{
    return (
        rect.x>=0 && 
        rect.y>=0 && 
        rect.x + rect.width < m.cols && 
        rect.x + rect.width < m.rows) ;
}

但是如果使用了&运算符,life will be much easier.

cpp 复制代码
bool rectIsInside(const cv::Rect& rect, const cv::Mat& image)
{
    cv::Rect bbox(0, 0, image.cols, image.rows);
    return (rect & bbox) == rect; // elegent and efficient
}

简洁、优雅、可读性强的实现方式。

相关推荐
Ms_lan1 分钟前
体育运动手环训练为何还需要蓝牙网关加持?
人工智能·蓝牙网关·北京桂花网·体育运动监测
skywalk81632 分钟前
参考paddlex的图像识别和目标检测,做一个精简的寻物小助手的推理服务器后台
服务器·人工智能·目标检测
xiaoye-duck5 分钟前
《算法题讲解指南:优选算法-哈希表》--58.存在重复元素I,59.存在重复元素II,60.字母异位词分组
数据结构·c++·哈希算法
hetao17338375 分钟前
2026-03-26 ZYZ28-CSP-XiaoMao Round 2 hetao1733837 的 record
c++·算法
weixin_446260856 分钟前
OpenClaw智能体应用第一集--飞书多智能体配置
人工智能·飞书
火柴-人9 分钟前
用 AI 调试渲染 Bug:renderdoc-mcp 进阶工作流
c++·人工智能·图形渲染·claude·codex·mcp·renderdoc
狙击主力投资工具12 分钟前
MACD形态推演:形背离的实战技巧-MACD指标的加速度特征-从速度的角度,对高低点结构进行分类
人工智能
梓䈑17 分钟前
【CMake】cmake实现属性传递的秘密(目标的默认输出路径 以及 如何修改输出路径)
c++·cmake
wangjialelele20 分钟前
现代C++:C++17新特性整理
c语言·开发语言·c++·visual studio code
HySpark21 分钟前
从“录音”到“决策”:一套会议总结与智能分析体系的技术落地实践
人工智能·机器学习·支持向量机