Opencv和python用于自动裁剪

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opencv和python用于自动裁剪相关的知识,希望对你有一定的参考价值。

我想自动裁剪图像。

我正在使用ImageMagick。

我正在使用的命令

 convert  3.jpg  -fuzz 10%  -trim     trim.jpg

enter image description here

enter image description here

我该如何解决 。

我认为设置的模糊因素有问题。

答案

如果你想用OpenCV做这个,一个好的起点可能是在做一些简单的处理去除图像中的噪点和小细节后,你可以找到图像的边缘,然后找到边界框并裁剪到该区域。但是在你的第二张图像的情况下,你可能需要做一些后处理,因为原始边缘可能会有一些噪音和边框。您可以逐个像素地执行此操作,或者另一个可能是矫枉过正的方法将查找图像中的所有轮廓并找到最大的边界框。使用此方法,您可以获得以下结果:First Image

而对于第二个:

Second Image

需要工作的部分是找到适用于所有图像的正确阈值方法。在这里,我使用不同的阈值来制作二进制图像,因为第一个主要是白色,第二个是有点暗。第一个猜测是使用平均强度作为线索。

希望这可以帮助!

编辑

这就是我使用一些预处理和动态阈值来使它适用于两个图像的方法:

im = cv2.imread('cloth.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
imgray = cv2.blur(imgray,(15,15))
ret,thresh = cv2.threshold(imgray,math.floor(numpy.average(imgray)),255,cv2.THRESH_BINARY_INV)
dilated=cv2.morphologyEx(thresh, cv2.MORPH_OPEN, cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(10,10)))
_,contours,_ = cv2.findContours(dilated,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)

我还检查了轮廓区域以去除非常大的轮廓:

new_contours=[]
for c in contours:
    if cv2.contourArea(c)<4000000:
        new_contours.append(c)

数字4000000是图像大小(宽度*高度)的估计,大轮廓应该具有接近图像大小的区域。

然后,您可以迭代所有轮廓,并找到整个边界框:

best_box=[-1,-1,-1,-1]
for c in new_contours:
   x,y,w,h = cv2.boundingRect(c)
   if best_box[0] < 0:
       best_box=[x,y,x+w,y+h]
   else:
       if x<best_box[0]:
           best_box[0]=x
       if y<best_box[1]:
           best_box[1]=y
       if x+w>best_box[2]:
           best_box[2]=x+w
       if y+h>best_box[3]:
           best_box[3]=y+h

然后你有best_box数组内所有轮廓的边界框。

以下是第三张图片的结果:Third Image

另一答案

您可以尝试隔离饱和通道,并按预期进行修剪。

# Convert to HSV, isolate saturation channel, and switch to format
# that supports extended paging.
convert source.jpg -colorspace HSV -channel S -separate /tmp/saturation.png

saturation channel

# Trim as before
convert /tmp/saturation.png -trim /tmp/trim.png

trim

# Capture results of -trim
GEO=$(identify -format '%wx%h%X%Y' /tmp/trim.png)

1232x1991 + 384 + 336

# Apply results to original image
convert source.jpg -crop $GEO trim.jpg

finish

另一答案

Kamyar Infinity方法的问题是当某些区域的背景颜色接近物体时,您无法获得物体的右边界。

设置为math.floor(numpy.average(imgray))的阈值对你没有帮助......例如:

enter image description here

即使阈值是完美的(手动调整),你也不能忽视图像右上角的那个小点。你需要过滤掉一些区域。例如:

enter image description here

实现这一目标的方法由opencv正式提供。

Creating Bounding boxes and circles for contours

这里给出的另一种方法可能很有用。 (与Kamyar Infinity基本相同,但添加了cv.inRandge)

Dealing with contours and bounding rectangle in OpenCV 2.4 - python 2.7

以上是关于Opencv和python用于自动裁剪的主要内容,如果未能解决你的问题,请参考以下文章

在 OpenCV 中自动检测和裁剪 ROI

使用 OpenCV 和 Python 裁剪图像的轮廓

使用Python从OpenCV中扫描裁剪矩形照片

如何使用 Python 和 OpenCV 裁剪图像中的多个 ROI

基于变化角的Opencv C++裁剪图像

OpenCV 和 python - 裁剪网络摄像头流并将其保存到文件