调整图像中的ROI大小

时间:2015-02-11 13:06:01

标签: image opencv image-processing

我有一张565 * 584的图像,显​​示为enter image description here

我希望在不改变图像大小的情况下将圆的半径减少一定数量的像素。我该怎么做?请解释或提出一些想法。谢谢。

3 个答案:

答案 0 :(得分:3)

我会使用ImageMagick和这样的侵蚀:

convert http://i.stack.imgur.com/c8lfe.jpg -morphology erode octagon:8 out.png

enter image description here

答案 1 :(得分:3)

如果你知道图像的背景是常数,就像在你的例子中一样,这很容易。

按照您希望缩小的比例调整整个图像的大小。然后以原始尺寸创建一个新图像并用背景颜色填充,然后将调整后的图像粘贴到其中心。

enter image description here

答案 2 :(得分:3)

以下是您在OpenCV Python中的表现方式。使用Mark Setchell的方法,只需指定一个圆形结构元素,以便您可以保持或尊重对象的圆形边缘。 OpenCV最接近的是椭圆模板。

因此:

import numpy as np # Import relevant packages - numpy and OpenCV
import cv2

# Read in image and threshold - convert to grayscale first
im = cv2.imread('c8lfe.jpg', 0) > 128

# Specify radius of ellipse
radius = 21

# Obtain structuring element, then erode image
se = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (radius, radius))

# Make sure you convert back to grayscale and multiply by 255
out = 255*(cv2.erode(im, se).astype('uint8'))

# Show the image, wait for user key, then close window and write image
cv2.imshow('Reduced shape', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('out.png', out)

我们得到:

enter image description here

请注意,形状右上角的小凹凸会发生变化。由于我们基本上缩小了物体的周长,因此撞击也会缩小。如果您希望在保持图像分辨率的同时保留对象的结构,请使用Mark Ransom的方法或我稍微修改过的方法。两者都显示如下。


然而,为了自足,我们当然可以做Mark Ransom所建议的。调整图像大小,初始化原始图像大小的空白图像,并将其放在中心:

import numpy as np # Import relevant packages - OpenCV and Python
import cv2

im = cv2.imread('c8lfe.jpg', 0) # Read in the image - grayscale
scale_factor = 0.75 # Set scale factor - We are shrinking the image by 25%

# Get the desired size (row and columns) of the shrunken image
desired_size = np.floor(scale_factor*np.array(im.shape)).astype('int')

# Make sure desired size is ODD for easier placement
if desired_size[0] % 2 == 0:
    desired_size[0] += 1
if desired_size[1] % 2 == 0:
    desired_size[1] += 1

# Resize the image.  Columns come first, followed by rows, which is why we 
# reverse the desired_size array
rsz = cv2.resize(im, tuple(desired_size[::-1]))

# Determine half width of both dimensions of shrunken image
half_way = np.floor(desired_size/2.0).astype('int')

# Create output image that is the same size as the input and find its centre
out = np.zeros_like(im, dtype='uint8')
centre = np.floor(np.array(im.shape)/2.0).astype('int')

# Place shrunken image in the centre of the larger output image
out[centre[0]-half_way[0]:centre[0]+half_way[0]+1, centre[1]-half_way[1]:centre[1]+half_way[1]+1] = rsz

# Show the image, wait for user key, then close window and write image
cv2.imshow('Reduced shape', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('out.png', out)

我们得到:

enter image description here


另一个建议

我还建议你做的是用零填充数组,然后将图像重新缩小回原始大小。您基本上会扩展原始图像的边框,使边框包含零。在这种情况下,我们会做Mark Ransom所建议的,但我们在内部工作,外出。

以下是使用OpenCV C ++填充矩阵的方法:Pad array with zeros- openCV。但是,在Python中,只需使用numpy' s pad函数:

import numpy as np # Import relevant packages - numpy and OpenCV
import cv2

# Read in image and threshold - convert to grayscale first
im = cv2.imread('c8lfe.jpg', 0)

# Set how many pixels along the border you want to add on each side
pad_radius = 75

# Pad the image
out = np.lib.pad(im, ((pad_radius, pad_radius), (pad_radius, pad_radius)), 'constant', constant_values=((0,0),(0,0)))

# Shrink it back to what the original size was
out = cv2.resize(out, im.shape[::-1])

# Show the image, wait for user key, then close window and write image
cv2.imshow('Reduced shape', out)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('out.png', out)

我们得到:

enter image description here