【问题标题】:Is there any way to crop an image inside a box?有没有办法在盒子里裁剪图像?
【发布时间】:2020-08-28 10:53:31
【问题描述】:

我只想裁剪框或矩形内的图像。我尝试了很多方法,但都没有奏效。

import cv2
import numpy as np

img  = cv2.imread("C:/Users/hp/Desktop/segmentation/add.jpeg", 0);
h, w = img.shape[:2]
# print(img.shape)
kernel = np.ones((3,3),np.uint8)

img2 = img.copy()

img2 = cv2.medianBlur(img2,5)
img2 = cv2.adaptiveThreshold(img2,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,\
            cv2.THRESH_BINARY,11,2)

img2 = 255 - img2
img2 = cv2.dilate(img2, kernel)
img2 = cv2.medianBlur(img2, 9)
img2 = cv2.medianBlur(img2, 9)

cv2.imshow('anything', img2)
cv2.waitKey(0)
cv2.destroyAllWindows()


position = np.where(img2 !=0)
x0 = position[0].min()
x1 = position[0].max()
y0 = position[1].min()
y1 = position[1].max()

print(x0,x1,y0,y1)

result = img[x0:x1,y0:y1]

cv2.imshow('anything', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出应该是正方形内的图像。

【问题讨论】:

  • 我认为这个问题是XY problem 的一个例子。告诉我们您尝试了什么以及您的尝试有什么问题。 “它不起作用”它不够专注
  • 使用形态变换来加强之前的线条
  • @AliRazaAbbasi 你用不同的图像和不同的情况问了这个问题here,你认为我的那个特殊情况的代码适用于所有情况!您应该已经注意到,在这种情况下,线不是直的,直接使用霍夫线变换,而且 ROI 的边缘不清晰,图像内部有很强的噪声。矩形本身也不容易被识别为最后一个问题,因此请尽量具体说明您的问题。

标签: python image numpy opencv image-processing


【解决方案1】:

用不同的颜色(例如红色)绘制正方形,以便与其他文字和背景区分开来。然后对其进行阈值处理,以获得黑白图像:该图像中的红线将是白色的。获取白色像素的坐标:从这个集合中,只选择两对 (minX, minY)(maxX,maxY)。它们是框的左上角和右下角(请记住,在图像中,0,0 点位于图像的左上角),您可以将它们用于crop the image

【讨论】:

    【解决方案2】:

    您可以为此使用轮廓检测​​。如果您的图像中基本上只有一个手绘矩形,我认为假设它是图像中最大的闭合轮廓就足够了。从那个轮廓,我们可以算出一个多边形/四边形近似,然后最终得到一个近似矩形。我将在开始时定义一些实用程序,我通常使用这些实用程序来让我在处理图像时更轻松:

    def load_image(filename):
        return cv2.imread(filename)
    
    def bnw(image):
        return cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
    
    def col(image):
        return cv2.cvtColor(image, cv2.COLOR_GRAY2RGB)
    
    def fixrgb(image):
        return cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    
    def show_image(image, figsize=(7,7), cmap=None):
        cmap = cmap if len(image.shape)==3 else 'gray'
        plt.figure(figsize=figsize)
        plt.imshow(image, cmap=cmap)
        plt.show()
    
    def AdaptiveThresh(gray):
        blur = cv2.medianBlur(gray, 5)
        adapt_type = cv2.ADAPTIVE_THRESH_GAUSSIAN_C
        thresh_type = cv2.THRESH_BINARY_INV
        return cv2.adaptiveThreshold(blur, 255, adapt_type, thresh_type, 11, 2)
    
    def get_rect(pts):
        xmin = pts[:,0,1].min()
        ymin = pts[:,0,0].min()
        xmax = pts[:,0,1].max()
        ymax = pts[:,0,0].max()
        return (ymin,xmin), (ymax,xmax)
    

    让我们加载图像并将其转换为灰度:

    image_name = 'test.jpg'
    image_original = fixrgb(load_image(image_name))
    image_gray = 255-bnw(image_original)
    show_image(image_gray)
    

    使用一些变形操作来增强图像:

    kernel = np.ones((3,3),np.uint8)
    d = 255-cv2.dilate(image_gray,kernel,iterations = 1)
    show_image(d)    
    

    找到边缘并增强/降噪:

    e = AdaptiveThresh(d)
    show_image(e)
    

    m = cv2.dilate(e,kernel,iterations = 1)
    m = cv2.medianBlur(m,11)
    m = cv2.dilate(m,kernel,iterations = 1)
    show_image(m)
    

    轮廓检测:

    contours, hierarchy = cv2.findContours(m, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
    
    total_area = np.prod(image_gray.shape)
    max_area = 0
    for cnt in contours:
        # Simplify contour
        perimeter = cv2.arcLength(cnt, True)
        approx = cv2.approxPolyDP(cnt, 0.03 * perimeter, True)
        area = cv2.contourArea(approx)
    
        # Shape is recrangular, so 4 points approximately and it's convex
        if (len(approx) == 4 and cv2.isContourConvex(approx) and max_area<area<total_area):
            max_area = cv2.contourArea(approx)
            quad_polygon = approx
    
    img1 = image_original.copy()
    img2 = image_original.copy()
    
    cv2.polylines(img1,[quad_polygon],True,(0,255,0),10)
    show_image(img1)
    tl, br = get_rect(quad_polygon)
    cv2.rectangle(img2, tl, br, (0,255,0), 10)
    show_image(img2)
    

    因此您可以看到近似多边形和相应的矩形,您可以使用它们进行裁剪。我建议您使用中值模糊和形态操作,例如腐蚀、膨胀、打开、关闭等,看看哪一组操作最适合您的图像;我真的不能从一张图片中说出什么是好的。您可以使用左上角和右下角坐标进行裁剪:

    show_image(image_original[tl[1]:br[1],tl[0]:br[0],:])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-01-11
      • 1970-01-01
      • 2022-06-14
      • 2011-08-04
      • 2014-11-02
      • 2013-05-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多