Opencv 和 python 用于自动裁剪
Opencv and python for auto cropping
我想自动裁剪图片。
我为此使用 ImageMagick。
我正在使用的命令
convert 3.jpg -fuzz 10% -trim trim.jpg
我该如何解决这个问题。
我认为设置的模糊因子有问题。
您可以尝试隔离饱和通道,并且 trim 符合预期。
# 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
# Trim as before
convert /tmp/saturation.png -trim /tmp/trim.png
# 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
如果你想用 OpenCV 做这个,一个好的起点可能是在做一些简单的处理以去除图像中的噪声和小细节之后,你可以找到图像的边缘,然后找到边界框和裁剪到那个区域。但是对于第二张图片,您可能需要进行一些 post 处理,因为原始边缘可能会包含一些噪点和边界。您可以逐个像素地执行此操作,或者另一种可能矫枉过正的方法是查找图像中的所有轮廓并查找最大的边界框。使用这个你可以得到以下结果:
第二个:
需要工作的部分是找到适用于所有图像的适当阈值方法。在这里,我使用不同的阈值来制作二值图像,因为第一个大部分是白色的,第二个是有点暗的。第一个猜测是使用平均强度作为线索。
希望对您有所帮助!
编辑
这就是我使用一些预处理和动态阈值使其适用于两个图像的方式:
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
数组中得到了所有轮廓的边界框。
这是第三张图片的结果:
Kamyar Infinity 方法的问题是当某些区域的背景颜色接近对象时,您无法获得对象的正确边界。
设置为math.floor(numpy.average(imgray))
的阈值对您没有帮助...
例如:
即使阈值完美(手动调整),也不能忽略图像右上角的那个小点。您需要过滤掉一些区域。
例如:
opencv官方给出了实现方法
Creating Bounding boxes and circles for contours
这里给出的另一种方法可能会有用。 (与 Kamyar Infinity 基本相同,但添加了 cv.inRandge)
我想自动裁剪图片。
我为此使用 ImageMagick。
我正在使用的命令
convert 3.jpg -fuzz 10% -trim trim.jpg
我该如何解决这个问题。
我认为设置的模糊因子有问题。
您可以尝试隔离饱和通道,并且 trim 符合预期。
# 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
# Trim as before
convert /tmp/saturation.png -trim /tmp/trim.png
# 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
如果你想用 OpenCV 做这个,一个好的起点可能是在做一些简单的处理以去除图像中的噪声和小细节之后,你可以找到图像的边缘,然后找到边界框和裁剪到那个区域。但是对于第二张图片,您可能需要进行一些 post 处理,因为原始边缘可能会包含一些噪点和边界。您可以逐个像素地执行此操作,或者另一种可能矫枉过正的方法是查找图像中的所有轮廓并查找最大的边界框。使用这个你可以得到以下结果:
第二个:
需要工作的部分是找到适用于所有图像的适当阈值方法。在这里,我使用不同的阈值来制作二值图像,因为第一个大部分是白色的,第二个是有点暗的。第一个猜测是使用平均强度作为线索。
希望对您有所帮助!
编辑
这就是我使用一些预处理和动态阈值使其适用于两个图像的方式:
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
数组中得到了所有轮廓的边界框。
这是第三张图片的结果:
Kamyar Infinity 方法的问题是当某些区域的背景颜色接近对象时,您无法获得对象的正确边界。
设置为math.floor(numpy.average(imgray))
的阈值对您没有帮助...
例如:
即使阈值完美(手动调整),也不能忽略图像右上角的那个小点。您需要过滤掉一些区域。 例如:
opencv官方给出了实现方法
Creating Bounding boxes and circles for contours
这里给出的另一种方法可能会有用。 (与 Kamyar Infinity 基本相同,但添加了 cv.inRandge)