j'ai donc essayé de coder A Python script, qui prend une image comme entrée, puis coupe un rectangle avec une couleur d'arrière-plan spécifique. Cependant, ce qui cause un problème pour mes compétences de codage, Est-ce que le rectangle n'est pas sur une position fixe dans chaque image (la position sera aléatoire).
Je ne comprends pas vraiment comment gérer les fonctions numpopiques. J'ai aussi lu quelque chose à propos de OpenCV, mais je suis totalement nouveau à cela. Jusqu'à présent, je viens de recadrer les images à travers la fonction "Croprop", mais je devrais ensuite utiliser des valeurs fixes.
C'est ainsi que l'image d'entrée pourrait regarder et maintenant, je voudrais détecter la position du rectangle jaune, puis récolter l'image à sa taille.
L'aide est appréciée, merci d'avance.
EDIT: @ Way de MarkSetchell fonctionne plutôt bien, mais a trouvé un problème pour une image de test différente. Le problème avec l'autre image est qu'il y a 2 petits pixels de même couleur au sommet et au bas de l'image, qui causent des erreurs ou une mauvaise récolte.
Ce que je vois, c'est des zones sombres et grises claires sur les côtés et le dessus, une zone blanche et un rectangle jaune avec des triangles gris à l'intérieur de la zone blanche.
La première étape que je suggère de convertir l'image de l'espace de couleur RVB en [~ # ~] HSV [~ # ~] Espace de couleur.
[.____] le [~ # ~] s [~ # ~] canal de couleur dans l'espace HSV, est le "canal de saturation des couleurs".
[.____] Toutes les zéros et les pixels jaunes sont au-dessus des zéros dans le canal S.
Stades suivants:
Voici le code:
import numpy as np
import cv2
# Read input image
img = cv2.imread('img.png')
# Convert from BGR to HSV color space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# Get the saturation plane - all black/white/gray pixels are zero, and colored pixels are above zero.
s = hsv[:, :, 1]
# Apply threshold on s - use automatic threshold algorithm (use THRESH_OTSU).
ret, thresh = cv2.threshold(s, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Find contours in thresh (find only the outer contour - only the rectangle).
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # [-2] indexing takes return value before last (due to OpenCV compatibility issues).
# Mark rectangle with green line
cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
# Assume there is only one contour, get the bounding rectangle of the contour.
x, y, w, h = cv2.boundingRect(contours[0])
# Invert polarity of the pixels inside the rectangle (on thresh image).
thresh[y:y+h, x:x+w] = 255 - thresh[y:y+h, x:x+w]
# Find contours in thresh (find the triangles).
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)[-2] # [-2] indexing takes return value before last (due to OpenCV compatibility issues).
# Iterate triangle contours
for c in contours:
if cv2.contourArea(c) > 4: # Ignore very small contours
# Mark triangle with blue line
cv2.drawContours(img, [c], -1, (255, 0, 0), 2)
# Show result (for testing).
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
S canal couleur S dans l'espace de couleur HSV:
[.____]
thresh
- S après seuil:
[.____]
thresh
après l'inversion de la polarité du rectangle:
[.____]
Résultat (rectangle et triangles sont marqués):
[.____]
Au cas où il y a des points de couleur en arrière-plan, vous pouvez recadrer le plus grand contour de couleur:
import cv2
import imutils # https://pypi.org/project/imutils/
# Read input image
img = cv2.imread('img2.png')
# Convert from BGR to HSV color space
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
# Get the saturation plane - all black/white/gray pixels are zero, and colored pixels are above zero.
s = hsv[:, :, 1]
cv2.imwrite('s.png', s)
# Apply threshold on s - use automatic threshold algorithm (use THRESH_OTSU).
ret, thresh = cv2.threshold(s, 0, 255, cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Find contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = imutils.grab_contours(cnts)
# Find the contour with the maximum area.
c = max(cnts, key=cv2.contourArea)
# Get bounding rectangle
x, y, w, h = cv2.boundingRect(c)
# Crop the bounding rectangle out of img
out = img[y:y+h, x:x+w, :].copy()
Dans OpenCV, vous pouvez utiliser InRange. Cela fait fondamentalement la couleur de la plage que vous avez des problèmes blanches et le reste noir. De cette façon, tout le jaune sera blanc.
Voici la documentation: https://docs.opencv.org/3.4/da/d97/Toryiel_threshold_inrange.html