Original-:
- Zuerst sollten Sie auch Ihr Originalbild einfügen.
- Zweitens,
minAreaRect
anders als boundingRect
zu verwenden, um die gedrehten Rechtecke zu finden.
aktualisieren:
Ich glaube nicht tun findContours
auf Canny Kanten eine Idee gut ist. Ich mache es einfach auf threshed binary image
, dann entfernen Sie die Konturen mit kleinen Flächen. So können wir die Grenze von Regionen bekommen. Dann, um zu beurteilen, ob die Region abgeschlossen ist oder nicht, ist es bis zu Ihrem mathematischen Wissen.
#!/usr/bin/python3
# 2017.12.09 00:25:47 CST
# 2017.12.09 14:26:01 CST
import cv2
import numpy as np
img = cv2.imread("test.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
th, threshed = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
_, cnts, _ = cv2.findContours(threshed,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
canvas = np.zeros_like(img, np.uint8)
H,W = img.shape[:2]
AREA = H*W
for cnt in cnts:
area = cv2.contourArea(cnt)
if(area<AREA/100):
continue
_ = cv2.drawContours(canvas, [cnt], -1, (0,255,0), 1, cv2.LINE_AA)
cv2.imwrite("result.png", canvas)
Update 2: Nachdem die Konturen der Regionen erhalten, dann, wie zu beurteilen, ob es vollständig ist oder nicht?
Sie sollten definieren, was abgeschlossen ist? In dieser Situation, die komplette Kachel bedeutet, es ist ein Viereck, vier Eckpunkte, fast gleiche Längen der Seite. Dann programmieren Sie den Zustand, um dem Computer zu sagen, wie er zu urteilen hat. Es ist Ihre Aufgabe, Sie sollten zuerst versuchen, es selbst zu lösen.
Gesamt Code und das Ergebnis:
#!/usr/bin/python3
# 2017.12.09 00:25:47 CST
# 2017.12.09 14:26:01 CST
# 2017.12.09 17:52:17 CST
import cv2
import numpy as np
## lambda: calc distance
dist = lambda pt1, pt2: ((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)**0.5
img = cv2.imread("img04.jpg")
## (1) filter, threshed
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
th, threshed = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)
## (2) findContours
_, cnts, _ = cv2.findContours(threshed,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
## (3) some variables
H,W = img.shape[:2]
AREA = H*W
xcnts = []
R = 0.8
## (4) judge wether the contour is belongs to a complete tile
for cnt in cnts:
## (4.1) filter by area
area = cv2.contourArea(cnt)
if(area<AREA/100):
continue
## (4.2) calc arpprox contour
arclen = cv2.arcLength(cnt, closed=True)
approx = cv2.approxPolyDP(cnt, arclen*0.02, closed=True)
## (4.3) filter by "complete ruler"
## "the complete tile means it is a quadrilateral, four corner points, almost equal lengths of side"
pts = np.array(approx).reshape(-1,2)
if len(pts) == 4:
lens = np.array(list(dist(pts[i], pts[(i+1)%4]) for i in range(4)))
flag = True
for x in lens:
if not (R< x/lens[0] < 1.0/R):
flag = False
continue
if flag:
xcnts.append(cnt)
## (5) draw and save
res = img.copy()
for cnt in xcnts:
cv2.drawContours(res, [cnt], -1, (0,255,0), -1, cv2.LINE_AA)
cv2.imwrite("00result.png", res)
Update 3 (Datum der letzten Aktualisierung):
ich den festen gedroschen Wert in der Verwendung mein code nur weil dein bild ein großes darlegt k Ursprung. Wie für dieses Bild
,
gibt es keine große dunkle, so dass die Schwellen Flag auf cv2.THRESH_OTSU
ändern und modifizieren, um AREA/20
oder größer ist, modifizieren, um die R kleiner wie der Bereich R=0.7
dreschen.
Dann bekomme ich das Ergebnis:
ähnliche Fragen:
(1) Image processing using opencv and python
(2) Python OpenCV - Trying to identify a completely visible tile (all four edges are visible) and draw a green contour edges
Dank für Ihre Antwort. Ich habe das Originalbild hinzugefügt. –
bei der Verwendung von BoundingRect wie vorgeschlagen, bekomme ich folgenden Fehler - (x, y, w, h) = cv2.minAreaRect (Kontur) ValueError: nicht genug Werte zu entpacken (erwartet 4, bekam 3) –
@Ankit ich testen mit Ihr Originalbild, und es ist nicht einfach, es zu erkennen. Und ich habe eine Frage in deinem Code gefunden. Nach der Erkennung "Canny Kanten" können wir die Kanten finden, aber die Kanten sind nicht kontinuierlich und geschlossen. Wenn wir also "FindContours" finden, finden wir die Konturen der diskontinuierlichen und offenen Kanten, nicht der Regionen. (Normalerweise finde ichContours auf gedroschenem Binärbild). Und in Ihrem Bild wurde das Rechteck in eine Raute umgewandelt, also auch das 'cv2.minAreaRect' (zur Erkennung eines gedrehten Rechtecks,' (x1, y2), (x2, y2), Winkel = cv2.minAreaRect (pts) ') wird ungültig. – Silencer