Introduction Je voulais quelque chose comme ça ↓ ↓ ↓
Le chiffre est trop bon marché.
Lorsqu'il est verbalisé, ** Détecter les objets d'une couleur et d'une taille spécifiques à partir d'images affichant des objets de différentes couleurs et tailles ** Je voulais le faire.
Je pense qu'il y a déjà beaucoup d'excellents articles de commentaires, mais si je ne les écris pas, je les oublierai bientôt, alors je les écrirai sous forme de mémorandum.
L'image est traitée dans les 4 étapes suivantes
Binarisation basée sur les informations de couleur
Détecter le contour
Classement des cas par taille
Superposez le contour sur l'image d'origine
** 1. Binarisation basée sur les informations de couleur ** ** 2. Détecter le contour **
import cv2
import numpy as np
#image"hoge.jpg "Lis
#La même image est lue deux fois avec des variables différentes. Un (img_c) pour le "traitement d'image",
#L'autre (img_c_Depuis l'origine) est "à afficher au-dessus du contour".
filename = "hoge.jpg "
input_img = filename
img_c = cv2.imread(input_img)
img_c_origin = cv2.imread(input_img)
#Prétraitement (flou)
#Les chiffres sont appropriés
for i in range(2):
img_c = cv2.GaussianBlur(img_c,(5,5),0)
#Canaux d'image séparés. cv2.Notez que les images lues par imread sont dans l'ordre "BGR" au lieu de "RGB"!
B, G, R = cv2.split(img_c)
#Il est binarisé dans chaque canal RVB.
#Il sera 1 si le pixel est de la couleur souhaitée et 0 sinon.
# -------- color condition ----------
R_low = 0
R_high = 100
G_low = 100
G_high = 200
B_low = 200
B_high = 250
# -----------------------------------
img_r_th = np.where((R < R_high) & (R > R_low), 1, 0)
img_g_th = np.where((G < G_high) & (G > G_low), 1, 0)
img_b_th = np.where((B < B_high) & (B > B_low), 1, 0)
#Multiplication de chaque élément, pas multiplication matricielle. Je l'aime parce que je peux le faire.
#ET logique(AND)C'est une image à prendre. Afin de rendre blanc l'objet détecté, il est multiplié par 255 à la fin.
img_th = img_r_th * img_g_th * img_b_th * 255
#Convertissez en uint8 pour l'utiliser comme argument pour le prochain findCOntours.
img_th = np.uint8(img_th)
#Détecte les contours.
contours = cv2.findContours(img_th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0]
Pour la raison pour laquelle le flou d'image (prétraitement) est nécessaire, le "prétraitement" de l'article suivant a été utile. Introduction à OpenCV pour l'apprentissage automatique
Cette fois, j'utilise RVB pour diverses raisons, mais il existe également un moyen de le détecter avec HSV. C'est intuitif, n'est-ce pas? Détection de contour d'objet
Cliquez ici pour plus de détails sur la détection des contours Plan: première étape
Bien que j'aie écrit diverses choses, la zone autour de la détection de contour est presque en train de se copier. Parce que c'est stupide ...
** 3. Caisse par taille ** ** 4. Affiché en superposition sur l'image d'origine **
# -------- scale condition ----------
Area_th_min = 1
Area_th_max = 1000
# -----------------------------------
#Définissez une liste pour stocker les contours souhaités
Active_contours = []
#Lorsque vous saisissez un contour dans contourArea, la zone de la zone entourée par le contour est renvoyée.
#En utilisant cela, seuls les objets actifs d'une taille spécifique (contour)_Stocker dans les contours.
for cont in contours:
if cv2.contourArea(cont) > Area_th_min and cv2.contourArea(cont) < Area_th_max:
Active_contours.append(cont)
#Vous pouvez utiliser drowContours pour superposer des contours sur une image.
#Pour plus de détails, reportez-vous à la section «Plan: première étape» ci-dessus.
cont_img = cv2.drawContours(img_c_origin, Active_contours, -1, (255,0,0), 3)
#Convertissez "BGR" en "RVB" pour l'affichage.
cont_img = cv2.cvtColor(cont_img, cv2.COLOR_BGR2RGB)
** Code entier **
detect_color.py
import cv2
import numpy as np
import matplotlib.pyplot as plt
#[[User specified parameters]]
# ------- color condition ----------
R_low = 200
R_high = 250
G_low = 60
G_high = 110
B_low = 80
B_high = 120
# -----------------------------------
# ------- scale condition -----------
Area_th_min = 1200
Area_th_max = 10000
# -----------------------------------
# Step 1 ---------------------------
filename = "hoge.jpg "
input_img = filename
img_c = cv2.imread(input_img)
img_c_origin = cv2.imread(input_img)
for i in range(2):
img_c = cv2.GaussianBlur(img_c,(5,5),0)
B, G, R = cv2.split(img_c)
img_g_th = np.where((G < G_high) & (G > G_low), 1, 0)
img_b_th = np.where((B < B_high) & (B > B_low), 1, 0)
img_r_th = np.where((R < R_high) & (R > R_low), 1, 0)
img_th = img_r_th * img_g_th * img_b_th * 255
img_th = np.uint8(img_th)
# Step 2 ---------------------------
contours = cv2.findContours(img_th, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)[0]
# Step 3 ---------------------------
Active_contours = []
for cont in contours:
if cv2.contourArea(cont) > Area_th_min and cv2.contourArea(cont) < Area_th_max:
Active_contours.append(cont)
# Step 4 ---------------------------
cont_img = cv2.drawContours(img_c_origin, Active_contours, -1, (255,0,0), 3)
cont_img = cv2.cvtColor(cont_img, cv2.COLOR_BGR2RGB)
img_c_origin = cv2.cvtColor(img_c_origin, cv2.COLOR_BGR2RGB)
# ------------- show images -------------
plt.gray()
plt.subplot(1,2,1)
plt.imshow(img_th, vmin=0, vmax=255, interpolation = 'none')
plt.title('Threshold')
plt.subplot(1,2,2)
plt.imshow(cont_img, interpolation = 'none')
plt.title('Contour')
plt.show()
# ----------------------------------------
Le code ci-dessus spécifie déjà une plage de R, G, B. Ici, si vous spécifiez le logo incroyablement cool de "The Demon Girl Next Door", qui est le titre anglais de "Machikado Mazoku", comme image d'entrée ...
Seul le "G" rose est détecté. Dans l'image de seuil, toutes les zones roses ont été détectées, mais à la suite de la classification par taille, seul G est resté.
Au fait, je pense que cette image de logo, le noir représente Shamiko et le rose représente la pêche, mais qu'en est-il ... Vous pouvez voir Machikado Mazoku sur Amapura, alors voyons tout le monde.
La fin
Recommended Posts