提取具有指定宽高比的子图像
Extracting subimage with a specified aspect ratio
我需要从图像中提取一个对象。我知道对象在图像中的位置,即对象所在的区域:该区域以一对坐标[xmin, ymin]和[xmax, ymax]提供。
我想修改这个区域的坐标(从而以适当的方式增加高度和宽度),以便提取具有指定宽高比的子图像。因此,我们有以下约束:
- 为避免切割对象不正确,区域的宽度和高度不得减小;
- 边界检查:区域大小的调整必须确保新坐标在图像内;
- 子图像的宽度/高度比例应该近似等于指定的长宽比。
如何解决这个问题?
UPDATE:一个可能的解决方案
我的问题的解决方案主要是Mark在这个答案中提出的算法。该算法的结果是一个比原始区域更宽或更高的新区域,并且能够在不移动原始区域中心的情况下获得非常接近指定的新长宽比(如果可行,则取决于该区域在原始图像中的位置)。该算法得到的区域可以通过以下算法进一步处理,以使宽高比更接近指定值。
for left=0:(xmin-1), // it tries all possible combinations
for right=0:(imgWidth-xmax), // of increments of the region size
for top=0:(ymin-1), // along the four directions
for bottom=0:(imgHeight-ymax),
x1 = xmin - left;
x2 = xmax + right;
y1 = ymin - top;
y2 = ymax + bottom;
newRatio = (x2 - x1) / (y2 - y1);
if (newRatio == ratio)
rect = [x1 y1 x2 y2];
return;
end
end
end
end
end
例子… 976行1239列的图片;一个初始区域[xmin ymin xmax ymax] = [570 174 959 957].
第一个算法(主处理)。
- 输入:初始区域和图像大小。
- 输出:产生新的区域r1 = [568 174 960 957],宽度= 392,高度= 783,所以宽高比等于0.5006。
第二个算法(后处理)。
- 输入:区域r1.
- 输出:新区域r2 = [568 174 960 958],宽度= 392,高度= 784,所以宽高比等于0.5。
obj_width = xmax - xmin
obj_height = ymax - ymin
if (obj_width / obj_height > ratio)
{
height_adjustment = ((obj_width / ratio) - (ymax - ymin)) / 2;
ymin -= height_adjustment;
ymax += height_adjustment;
if (ymin < 0)
{
ymax -= ymin;
ymin = 0;
}
if (ymax >= image_height)
ymax = image_height - 1;
}
else if (obj_width / obj_height < ratio)
{
width_adjustment = ((obj_height * ratio) - (xmax - xmin)) / 2;
xmin -= width_adjustment;
xmax += width_adjustment;
if (xmin < 0)
{
xmax -= xmin;
xmin = 0;
}
if (xmax >= image_width)
xmax = image_width - 1;
}
让我们从你的区域开始:一个w x h以点p为中心的矩形。您希望扩展此区域,使其具有宽高比r。这个想法是扩展宽度或高度:
- (微不足道的情况下)如果 w h / = = r ,然后返回。
- 计算 w h ' = x r 。
- 如果w'> w,则生成的区域宽度w',高度h,中心p。
- 否则,生成的区域宽度w,高度h' = w/r,中心p。
- 移动中心p以跟随图像的边缘,如果它必须被剪切,例如,如果生成区域的左上角点在图像的外面:让u =生成区域的左上角点,并且d = (min(u.x,0), min(u.y,0))。那么,最终的中心将是p' = p - d。该区域的右下方也类似。
- 将生成的区域剪辑到图像。
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 彩色图像的卤化物处理平均值
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 重新定位图像时如何前进到下一个内存块
- 如何使用按钮更新GTK3图像以使用C++从相机捕获图片
- 为什么 BMP 图像上的 imwrite 会卡住/不返回?
- Gstreamer:每 5 秒使用多文件墨水保存图像/jpeg
- 如何使用CImg打开图像?
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 提取具有指定宽高比的子图像