cv2.findContours
лучше работает с двоичным изображением. Таким образом, я порог своего входного изображения
, и я получаю это пороговое изображение .
Затем я пытался найти и обрезать эти два контура. В результате я вижу маленький черный блок для одного из контуров
Когда я пробую другой пример, я вижу результат, как и ожидал. Моя цель - найти верхнюю и нижнюю сторону белой полосы.
Вот минимальный воспроизводимый пример.
import cv2
import numpy as np
frame = cv2.imread('frame8.png')
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
hsv = cv2.cvtColor(frame, cv2.COLOR_RGB2HSV)
lower_limit = np.array([0, 0, 94])
upper_limit = np.array([255, 255, 255])
mask = cv2.inRange(hsv, lower_limit, upper_limit) #created a mask to remove background
mask_inv = cv2.bitwise_not(mask)
bg = cv2.bitwise_and(frame, frame, mask=mask)
fg = cv2.bitwise_and(frame, frame, mask=mask_inv)
gray = cv2.cvtColor(bg,cv2.COLOR_RGB2GRAY)
thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY_INV)[1] #findContours function works better with binary images
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) #remove noise
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
cv2.imshow('thres',thresh)
cntrs = cv2.findContours(thresh, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cntrs = cntrs[0] if len(cntrs) == 2 else cntrs[1]
area_thresh = 5000
cnt = 0
for c in cntrs:
area = cv2.contourArea(c)
if area > area_thresh:
cnt= cnt + 1
if cnt > 0:
rect = cv2.minAreaRect(c) #minArearect returns - ( center (x,y), (width, height), angle of rotation ).
box = cv2.boxPoints(rect) # The function finds the four vertices of a rotated rectangle.
box = np.int0(box) #converting numbers to integer
# crop image inside bounding box
centerX = rect[0][0]
centerY = rect[0][1]
W = rect[1][0] #width of contour
H = rect[1][1] #height of contour
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
angle = rect[2]
rotated = False
if angle < -45:
angle += 90
rotated = True
center = (round(centerX), round(centerY))
size = (int((x2 - x1)), int( (y2 - y1)))
M = cv2.getRotationMatrix2D((size[0] / 2, size[1] / 2), angle, 1.0)
cropped = cv2.getRectSubPix(frame, size, center) #crop contour
cropped = cv2.warpAffine(cropped, M, size) #rotate contour using 2D-RotationMatrix
croppedW = W if not rotated else H
croppedH = H if not rotated else W
image = cv2.getRectSubPix(
cropped, (int(croppedW ), int(croppedH)), (size[0] / 2, size[1] / 2)) #crop contour
for x in range(0, image.shape[0]):
for y in range(0, image.shape[1]):
if image[x, y, 0] > 50 or image[x, y, 1] > 50 or image[x, y, 2] > 50:
image[x, y, 0] = 0
image[x, y, 1] = 0
image[x, y, 2] = 0
if croppedH > croppedW:
if cnt == 1:
output1 = image[0:image.shape[0], 0: image.shape[1]]
if cnt == 2:
output2 = image[0:image.shape[0], 0: image.shape[1]]
cv2.imshow('output2',output2)
cv2.imshow('output1',output1)
cv2.waitKey(0)