图像处理 - 我需要找到任何quadrilater的4个角

时间:2016-07-30 18:51:16

标签: java image-processing

我需要在我的图像中应用cvWarpPerspective进行转换

但要做到这一点,我需要将ROI的角落作为参数传递,我不能手动操作,因为我有306张图像,这将花费很多时间。

我已经尝试过Harris Corner探测器,Susan和几个imagej插件,但我尝试过的每个算法,不仅可以检测到角落,还可以检测更多点,而我只需要角落。 (如果我将更多点作为参数传递,最终图像会变形)

有什么建议吗?

1 个答案:

答案 0 :(得分:6)

使用Harris角点探测器的想法很好,但为了只获得角落,你需要做一些预处理。

  1. 阈值图像并仅获取大于0的值.opencv阈值函数。 enter image description here

  2. 找到两个连接的组件。 opencv findContours

  3. 找到每个组件的凸包。 opencv convexhull
  4. 填充凸包。 opencv fillPoly
  5. enter image description here

    1. 运行Harris角点探测器。 opencv特征探测器哈里斯
    2. enter image description here

      1. 做最大限制抑制。对于每个角落,如果他是新角落图像中的最大角落插入,则查看他的邻居,否则将其归零。
      2. enter image description here

        1. 取八个最突出的角落。 4 x corrdinate左边一个是左qaudrilater而右边4个是右四边形
        2. 不是Java代码,但python实现希望它足够有用:

          import cv2
          import numpy as np
          
          # Params
          neigbrhoodSize = 5
          
          # Read img
          img = cv2.imread('AIL6s.png')
          img = img[:,:,0]
          
          # Threshold
          Ithresh = img
          Ithresh[img > 0] = 1
          
          # Find contour
          fillImage = np.zeros(Ithresh.shape)
          im, contours, hierarchy = cv2.findContours(Ithresh.astype(np.uint8),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE )
          hulls = []
          for contour in contours:
          
              # Find convex hull for each area
              hull = cv2.convexHull(contour)
              hulls.append(hull)
          
          # Fill the convex area
          cv2.fillPoly(fillImage, hulls, 255)
          
          # Run corner detection
          corners = cv2.cornerHarris(fillImage.astype(np.uint8), 3, 3, 0.05)
          
          # Run max suppression
          maxCorners = corners.flatten().argsort()[-50:][::-1]
          maxCornersYX = np.unravel_index(maxCorners,corners.shape)
          cornersMaxSupression = np.zeros_like(corners)
          for i in range(len(maxCorners)):
          
              # Look at the neighborhood of the point. If it is the max value insert 1 to cornersMaxSupression else insert 0
              pointX = maxCornersYX[1][i]
              pointY = maxCornersYX[0][i]
              maxArea = np.max(corners[pointY-neigbrhoodSize:pointY+neigbrhoodSize,pointX-neigbrhoodSize:pointX+neigbrhoodSize])
              currentMax = np.max(cornersMaxSupression[pointY-neigbrhoodSize:pointY+neigbrhoodSize,pointX-neigbrhoodSize:pointX+neigbrhoodSize])
              if maxArea==corners[pointY, pointX] and currentMax==0:
                  cornersMaxSupression[pointY, pointX] = 1
          
          # Take the eight max values of cornersMaxSupression
          eightMaxCorners = corners.flatten().argsort()[-8:][::-1]
          eightMaxCornersYX = np.unravel_index(eightMaxCorners,corners.shape)
          
          # Divide the image to the two small images
          fillImage[:,1:fillImage.shape[1]/2] = fillImage[:,1:fillImage.shape[1]/2]*2