OpenCV中对ROI执行boxFilter的方法及核超出ROI时的处理逻辑咨询
问题解答
当前代码的行为
你当前代码里的image(roi)是原图像ROI区域的Mat引用,但这个引用的边界被限定为ROI的边缘。当boxFilter处理这个ROI Mat时,会默认采用BORDER_DEFAULT(镜像填充)的边界策略,此时如果滤波核超出ROI范围,程序只会使用BorderType指定的边界填充值,不会访问ROI之外但仍在原图像范围内的像素。
实现你需要的逻辑(调用ROI外的原图像素)
要让滤波核超出ROI时用到原图中ROI外的像素,有两种高效实现方式:
方法1:对完整原图滤波后提取ROI结果
直接在完整原图像上执行滤波,之后截取ROI区域作为输出,这样滤波计算会自然包含ROI外的原图像素:
cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR); cv::Rect roi(10, 10, 64, 64); cv::Mat full_output; // 对完整原图执行boxFilter cv::boxFilter(image, full_output, -1, cv::Size(scale_size, scale_size)); // 提取滤波结果中的ROI区域 cv::Mat output = full_output(roi);
方法2:截取包含核扩展范围的子图后滤波(适合大原图)
如果原图尺寸很大,对完整图滤波效率较低,可以先计算滤波核需要的扩展范围,从原图中截取包含ROI和核扩展区域的子图,再对这个子图滤波,最后提取对应ROI的结果:
cv::Mat image = cv::imread(argv[1], CV_LOAD_IMAGE_COLOR); cv::Rect roi(10, 10, 64, 64); int k = scale_size; int half_k = k / 2; // 计算扩展后的子图Rect(确保不超出原图范围) cv::Rect extended_roi( std::max(0, roi.x - half_k), std::max(0, roi.y - half_k), std::min(image.cols - (roi.x - half_k), roi.width + k), std::min(image.rows - (roi.y - half_k), roi.height + k) ); cv::Mat sub_image = image(extended_roi); cv::Mat sub_output; cv::boxFilter(sub_image, sub_output, -1, cv::Size(k, k)); // 从子图的滤波结果中提取对应原ROI的区域 cv::Mat output = sub_output(cv::Rect(half_k, half_k, roi.width, roi.height));
内容的提问来源于stack exchange,提问作者EnJ
相关产品推荐
相关产品推荐

