【问题标题】:Segment the collaged images using python使用python分割拼贴图像
【发布时间】:2021-02-28 17:24:24
【问题描述】:

我的问题陈述是通过应用边界框将拼贴图像分割成单独的图像。我已经使用 opencv 的精明边缘检测方法解决了这个问题:

代码:

import numpy as np 
import os 
import cv2 
import matplotlib.pyplot as plt 
  
   
# defining the canny detector function 
   
# here weak_th and strong_th are thresholds for 
# double thresholding step 
def Canny_detector(img, weak_th = None, strong_th = None): 
      
    # conversion of image to grayscale 
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
       
    # Noise reduction step 
    img = cv2.GaussianBlur(img, (5, 5), 1.4) 
       
    # Calculating the gradients 
    gx = cv2.Sobel(np.float32(img), cv2.CV_64F, 1, 0, 3) 
    gy = cv2.Sobel(np.float32(img), cv2.CV_64F, 0, 1, 3) 
      
    # Conversion of Cartesian coordinates to polar  
    mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees = True) 
       
    # setting the minimum and maximum thresholds  
    # for double thresholding 
    mag_max = np.max(mag) 
    if not weak_th:weak_th = mag_max * 0.1
    if not strong_th:strong_th = mag_max * 0.5
      
    # getting the dimensions of the input image   
    height, width = img.shape 
       
    # Looping through every pixel of the grayscale  
    # image 
    for i_x in range(width): 
        for i_y in range(height): 
               
            grad_ang = ang[i_y, i_x] 
            grad_ang = abs(grad_ang-180) if abs(grad_ang)>180 else abs(grad_ang) 
               
            # selecting the neighbours of the target pixel 
            # according to the gradient direction 
            # In the x axis direction 
            if grad_ang<= 22.5: 
                neighb_1_x, neighb_1_y = i_x-1, i_y 
                neighb_2_x, neighb_2_y = i_x + 1, i_y 
              
            # top right (diagnol-1) direction 
            elif grad_ang>22.5 and grad_ang<=(22.5 + 45): 
                neighb_1_x, neighb_1_y = i_x-1, i_y-1
                neighb_2_x, neighb_2_y = i_x + 1, i_y + 1
              
            # In y-axis direction 
            elif grad_ang>(22.5 + 45) and grad_ang<=(22.5 + 90): 
                neighb_1_x, neighb_1_y = i_x, i_y-1
                neighb_2_x, neighb_2_y = i_x, i_y + 1
              
            # top left (diagnol-2) direction 
            elif grad_ang>(22.5 + 90) and grad_ang<=(22.5 + 135): 
                neighb_1_x, neighb_1_y = i_x-1, i_y + 1
                neighb_2_x, neighb_2_y = i_x + 1, i_y-1
              
            # Now it restarts the cycle 
            elif grad_ang>(22.5 + 135) and grad_ang<=(22.5 + 180): 
                neighb_1_x, neighb_1_y = i_x-1, i_y 
                neighb_2_x, neighb_2_y = i_x + 1, i_y 
               
            # Non-maximum suppression step 
            if width>neighb_1_x>= 0 and height>neighb_1_y>= 0: 
                if mag[i_y, i_x]<mag[neighb_1_y, neighb_1_x]: 
                    mag[i_y, i_x]= 0
                    continue
   
            if width>neighb_2_x>= 0 and height>neighb_2_y>= 0: 
                if mag[i_y, i_x]<mag[neighb_2_y, neighb_2_x]: 
                    mag[i_y, i_x]= 0
   
    weak_ids = np.zeros_like(img) 
    strong_ids = np.zeros_like(img)               
    ids = np.zeros_like(img) 
       
    # double thresholding step 
    for i_x in range(width): 
        for i_y in range(height): 
              
            grad_mag = mag[i_y, i_x] 
              
            if grad_mag<weak_th: 
                mag[i_y, i_x]= 0
            elif strong_th>grad_mag>= weak_th: 
                ids[i_y, i_x]= 1
            else: 
                ids[i_y, i_x]= 2
       
       
    # finally returning the magnitude of 
    # gradients of edges 
    return mag 
   
frame = cv2.imread(r"image.jpg")  
# calling the designed function for 
# finding edges 
canny_img = Canny_detector(frame) 

有了这个,我得到了一个精确的边缘检测图像,如下所示:

现在我想使用外边缘分割拼贴图像。如何达到预期效果?

预期结果:

【问题讨论】:

    标签: python opencv image-processing image-segmentation canny-operator


    【解决方案1】:

    这是在 Python OpenCV 中执行此操作的一种方法。

     - Read the input
     - Convert to gray
     - Threshold and invert
     - Apply morphology open and then close to clean up most of the extraneous spots and make cleaner boundaries
     - Get the external contours
     - Loop over each contour and get the bounding boxes, crop and save the results
    

    输入:

    import cv2
    import numpy as np
    
    # read image
    img = cv2.imread('rooms.jpg')
    
    # convert to gray
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # threshold on white
    thresh = cv2.threshold(gray, 245, 255, cv2.THRESH_BINARY)[1]
    
    # invert
    thresh = 255 - thresh
    
    # apply morphology to ensure regions are filled and remove extraneous noise
    kernel = np.ones((3,3), np.uint8)
    morph = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
    kernel = np.ones((15,15), np.uint8)
    morph = cv2.morphologyEx(morph, cv2.MORPH_CLOSE, kernel)
    
    # get only external contours
    contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    contours = contours[0] if len(contours) == 2 else contours[1]
    
    # get bounding boxes
    i = 1
    for cntr in contours:
        # get bounding boxes
        x,y,w,h = cv2.boundingRect(cntr)
        print(i,x,y,w,h)
        crop = img[y:y+h, x:x+w]
        cv2.imwrite("rooms_crop_{0}.jpg".format(i), crop)
        i = i + 1
    
    # save threshold and morph
    cv2.imwrite("rooms_thresh.jpg",thresh)
    cv2.imwrite("rooms_morph.jpg",thresh)
    
    # show thresh and morph 
    cv2.imshow("thresh", thresh)
    cv2.imshow("morph", morph)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    阈值图像:

    形态清洁图像:

    裁剪图像:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2022-11-19
      相关资源
      最近更新 更多