繁体   English   中英

使用 opencv python 检测二进制图像中的补丁

[英]to detect patches in binary images using opencv python

我想在此处检测输入图像描述中的所有补丁图像,我附上了用于检测它们的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt


image=cv2.imread("bw2.jpg",0)

# convert to RGB
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
# convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
# create a binary thresholded image
_, binary = cv2.threshold(gray, 0, 500, cv2.THRESH_BINARY_INV)
# show it
plt.imshow(gray, cmap="gray")
plt.show()
# find the contours from the thresholded image
contours, hierarchy = cv2.findContours(gray, cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
print("contours:",contours)
# draw all contours
for c in contours:
if cv2.contourArea(c) < 3000:
    continue

(x, y, w, h) = cv2.boundingRect(c)
#cv2.rectangle(image, (x,y), (x+w,y+h), (0, 255, 0), 2)

## BEGIN - draw rotated rectangle
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image,[box],0,(255,51,255),2)

# show the image with the drawn contours
plt.imshow(image)
#plt.imshow(im3)

cv2.imwrite("detectImg2.png",image)
plt.show()

我得到 output 图像,在这里输入图像描述

我想检测所有这些,谁能告诉我如何实现这一点我是图像处理的新手

下面是我如何使用 Python OpenCV 提取和旋转图像中的每个 blob。

  • 读取输入
  • 转换为灰色
  • 临界点
  • 打开和关闭应用形态以清洁小斑点
  • 获取所有外部轮廓
  • 循环遍历每个轮廓并执行以下操作:
  • 在输入图像的副本上绘制轮廓
  • 获取轮廓的旋转矩形并提取其中心、尺寸和旋转角度
  • 获取旋转矩形的角
  • 在输入的另一个副本上绘制旋转的矩形
  • 校正图像未旋转的旋转角度
  • 使用填充的旋转矩形生成蒙版图像
  • 将蒙版图像应用于形态清洁图像以去除附近的其他白色区域
  • 使用中心和校正的旋转角度获取仿射扭曲矩阵
  • 使用 warpAffine 未旋转蒙版图像
  • 获取未旋转图像中一个斑点的轮廓
  • 获取轮廓边界框
  • 裁剪蒙版图像(或交替裁剪输入图像)
  • 保存裁剪的图像
  • 退出循环
  • 保存轮廓和 rotrect 图像


输入:

在此处输入图像描述

import cv2
import numpy as np

image = cv2.imread("bw2.jpg")
hh, ww = image.shape[:2]

# convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# create a binary thresholded image
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

# apply morphology
kernel = np.ones((7,7), np.uint8)
clean = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
kernel = np.ones((13,13), np.uint8)
clean = cv2.morphologyEx(clean, cv2.MORPH_CLOSE, kernel)


# get external contours
contours = cv2.findContours(clean, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]

contour_img = image.copy()
rotrect_img = image.copy()
i = 1
for c in contours:
    # draw contour on input
    cv2.drawContours(contour_img,[c],0,(0,0,255),2)

    # get rotated rectangle from contour
    # get its dimensions
    # get angle relative to horizontal from rotated rectangle
    rotrect = cv2.minAreaRect(c)
    (center), (width,height), angle = rotrect
    box = cv2.boxPoints(rotrect)
    boxpts = np.int0(box)

    # draw rotated rectangle on copy of image
    cv2.drawContours(rotrect_img,[boxpts],0,(0,255,0),2)

    # from https://www.pyimagesearch.com/2017/02/20/text-skew-correction-opencv-python/
    # the `cv2.minAreaRect` function returns values in the
    # range [-90, 0); as the rectangle rotates clockwise the
    # returned angle tends to 0 -- in this special case we
    # need to add 90 degrees to the angle
    if angle < -45:
        angle = -(90 + angle)

    # otherwise, check width vs height
    else:
        if width > height:
            angle = -(90 + angle)

        else:
            angle = -angle

    # negate the angle for deskewing
    neg_angle = -angle

    # draw mask as filled rotated rectangle on black background the size of the input
    mask = np.zeros_like(clean)
    cv2.drawContours(mask,[boxpts],0,255,-1)

    # apply mask to cleaned image
    blob_img = cv2.bitwise_and(clean, mask)

    # Get rotation matrix
    #center = (width // 2, height // 2)
    M = cv2.getRotationMatrix2D(center, neg_angle, scale=1.0)
    #print('m: ',M)

    # deskew (unrotate) the rotated rectangle
    deskewed = cv2.warpAffine(blob_img, M, (ww, hh), flags=cv2.INTER_CUBIC, borderMode=cv2.BORDER_REPLICATE)

    # threshold it again
    deskewed = cv2.threshold(deskewed, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)[1]

    # get bounding box of contour of deskewed rectangle
    cntrs = cv2.findContours(deskewed, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
    cntr = cntrs[0]
    x,y,w,h = cv2.boundingRect(cntr)

    # crop to white region
    crop = deskewed[y:y+h, x:x+w]

    # alternately crop the input
    #crop = image[y:y+h, x:x+w]

    # save deskewed image
    cv2.imwrite("bw2_deskewed_{0}.png".format(i),crop)
    print("")
    i = i + 1

# save contour and rot rect images
cv2.imwrite("bw2_contours.png",contour_img)
cv2.imwrite("bw2_rotrects.png",rotrect_img)

# display result, though it won't show transparency
cv2.imshow("thresh", thresh)
cv2.imshow("clean", clean)
cv2.imshow("contours", contour_img)
cv2.imshow("rectangles", rotrect_img)
cv2.waitKey(0)
cv2.destroyAllWindows()


轮廓图:

在此处输入图像描述

旋转矩形图像:

在此处输入图像描述

前 3 张未旋转的图像:

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

仿射扭曲旋转角度:

13.916877746582031
-42.87890625
18.8118896484375
-44.333797454833984
-38.65980911254883
-37.25965881347656
8.806793212890625
14.931419372558594
-37.405357360839844
-34.99202346801758
35.537681579589844
-35.350345611572266
-42.3245735168457
50.12316131591797
-42.969085693359375
52.750038146972656
45.0


您的代码对于检测这些补丁是正确的,这里只有一个小错误

if cv2.contourArea(c) < 3000:
    continue

将 3000 减少到 100 或更低的值,因为您给出的条件是低于 3000 的轮廓可以忽略

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM