[PYTHON] J'ai compté les grains

Articles publiés précédemment Mémorandum sur le nombre de cellules

Un script qui compte les grains fabriqués en tâtonnant de différentes manières

Je l'ai en fait mis en œuvre et j'ai réussi à l'amener à un niveau utilisable, donc je vais le laisser comme mémo.

Objectif

Le degré de saleté est évalué en comptant le nombre de particules dans le liquide. Ce que l'on appelle la qualité NAS Une mesure précise est possible avec un équipement extrêmement coûteux. (↑ Bien sûr, je n'y arriverai pas si je peux faire ça)

Cependant, le jugement approximatif est un jugement porté par la personne qui examine l'échantillon. Tout d'abord, le but est de tracer une ligne pour réduire la gamme de gabagaba et la niveler.

Environnement de création

Windows10 64bit Jupiter Notebook Python 3.6.10 opencv 3.4.2.17 numpy 1.19.0 matplotlib 3.2.2

Bibliothèque

cap_save.ipynb


import cv2
import sys
import os
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import time
from datetime import datetime

Fondamentalement, le traitement d'image à l'aide d'opencv est le principal, alors utilisez-le dans cet ensemble.

Enregistrer l'image

cap_save.ipynb


#Paramètre de destination d'enregistrement de l'image capturée
dir_path_class00 = 'Spécifiez le répertoire de sauvegarde/01_class00'
dir_path_class0 = 'Spécifiez le répertoire de sauvegarde/01_class01'
#… Ci-dessous, définissez le montant requis

#Nom du fichier image enregistré
filename1 = 'original_img'#L'image originale
filename2 = 'processing_img'#Image traitée

#Créer un répertoire de sauvegarde(Pas de changement)
os.makedirs(dir_path_class00,exist_ok=True)
os.makedirs(dir_path_class0,exist_ok=True)
#… Ci-dessous, définissez le montant requis

#Jointure de chemin de fichier(L'image originale:1 et image traitée:2 Utilisez le nom de fichier lors de l'enregistrement)
base_path_00_org = os.path.join(dir_path_class00,filename1)
base_path_00_proc = os.path.join(dir_path_class00,filename2)

base_path_0_org = os.path.join(dir_path_class0,filename1)
base_path_0_proc = os.path.join(dir_path_class0,filename2)
#… Ci-dessous, définissez le montant requis

#Date de sauvegarde de l'image(* Mois * Soleil * Heure * Minute)
datename = datetime.now().strftime('%m%d%H%M')

#Réglage du nom lors de l'enregistrement d'une image(Lors du changement, changez la pièce correspondante)
name1 = "cell"
name2 = ".jpg "

À proprement parler, il traite principalement de l'ancien NAS, et non de l'ISO. Pour la destination de sauvegarde, nous avons créé les destinations de sauvegarde de l'ancien niveau standard 00 à 12.

Je voulais conserver l'image d'origine et l'image traitée (encadrée), j'ai donc défini deux.

Après cela, listez les scripts nécessaires pour créer le répertoire et c'est OK.

Lire la spécification de l'image

cap_save.ipynb


#Chargement de l'image détectée(Le changement est à la fin ~.jpg uniquement)                   
img = cv2.imread('Spécifiez la destination d'enregistrement et le nom de fichier de l'image que vous souhaitez vérifier',1)
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

Même si la partie de l'image capturée était cv2.VideoCapture (), elle pouvait être traitée sans aucun problème. (Il est nécessaire de modifier la partie de traitement telle que la binarisation réelle.) Cependant, je ne pouvais pas le reconnaître en raison du problème de compatibilité entre la caméra USB utilisée pour le PC que j'essayais de mettre en œuvre et Opencv. Passé au traitement à partir de la sélection d'image. (Est-ce à cause du firmware dédié? J'ai demandé au fabricant, mais je n'ai pas encore répondu)

S'il s'agit d'une caméra USB sur le marché, elle fonctionne et peut être traitée sans aucun problème, donc ça va. Même avec une caméra PC (● `・ ω ・) ゞ <ok!

Partie de traitement

cap_save.ipynb


#Taille de l'image
w, h, = (640, 480)
#grossissement
mag = 1

#Processus 1
img_blur = cv2.GaussianBlur(img_gray,(5,5),1)
#Ensemble de noyau
kernel = np.ones((1,1),dtype=np.uint8)
img_erode = cv2.erode(img_gray,kernel)

def onTrackbar(position):
    global threshold
    threshold = position
cv2.namedWindow("img")
threshold = 100
cv2.createTrackbar("track","img",threshold,255,onTrackbar)

n = 0

while True:
    key = cv2.waitKey(1) & 0xFF
    ret, img_th = cv2.threshold(img_blur,threshold,255,cv2.THRESH_BINARY)
    __,contours, hierarchy = cv2.findContours(img_th.astype(np.uint8),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
    img_raw = cv2.resize(img,(w*mag, h*mag))
    img_cut = cv2.drawContours(img_raw, contours, -1,(0,255,255),1)
    #print(len(contours))
    cv2.imshow("img",img_th)
    cv2.imshow("scr",img_cut)
    if key == ord('a'):
        answer = len(contours)
        print("Le nombre de comptage est:",answer,"Pièces")
    
    if key == 27:
        break

Comme l'un des problèmes, le seuil est spécifié au moment de la détection du contour, mais s'il est fait avec une valeur fixe, il est inévitable. Un problème est survenu à savoir que le contour n'a pas été détecté en fonction de l'image. Créé pour que la valeur de seuil soit modifiée par la barre de piste.

Cette zone a été créée en faisant référence au parcours d'Udemy.

Après cela, il était possible de détecter dans une certaine mesure par un traitement d'érosion en raison de la relation entre le grossissement de l'objectif et le nombre de pixels de l'appareil de mesure. J'ajoute.

Je pense que cette zone peut être gérée en la modifiant en fonction de l'objet détecté. Après cela, le nombre de contours détectés est réglé sur «len (contours)» lorsque le contour est détecté.

J'ai eu les moments les plus difficiles ici. En parlant de satisfaction, le grand cadre extérieur de l'image que vous souhaitez détecter a également été compté. Pour être honnête, c'est subtil, mais j'ai abandonné parce que c'est la limite dans mon esprit maintenant.

2020-09-03.png

Si vous déplacez la barre de piste comme ceci, vous pouvez compter à partir de la détection de contour pour le moment.

Jugement d'après le nombre de chefs d'accusation

cap_save.ipynb


if answer == 1:
    cv2.imwrite((base_path_00_org + "_" + str(answer) + "cell" + "_" + datename + str(n) + ".jpg "),img)
    cv2.imwrite((base_path_00_proc + "_" + str(answer) + "cell" + "_" + datename + str(n) + ".jpg "),img_cut)
    n += 1
    print("le grade nas est:C'est équivalent à 00.")

elif answer == 2:
    cv2.imwrite((base_path_0_org + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img)
    cv2.imwrite((base_path_0_proc + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img_cut)
    n += 1
    print("le grade nas est:C'est équivalent à 0.")

elif 3 <= answer < 5:
    cv2.imwrite((base_path_1_org + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img)
    cv2.imwrite((base_path_1_proc + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img_cut)
    n += 1
    print("le grade nas est:C'est équivalent à 1.")

… Par la suite, définissez le montant requis.

elif 5780 <= answer:
    cv2.imwrite((base_path_12_org  + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img)
    cv2.imwrite((base_path_12_proc + "_" + str(answer) + name1 + "_" + datename + str(n) + name2),img_cut)
    n += 1
    print("le grade nas est:C'est équivalent à 12.")
    
cv2.destroyAllWindows()

Pour le seuil (valeur de consigne) qui est à la base du jugement, reportez-vous à la classe de qualité NAS. A proprement parler, il est impossible de porter un jugement précis sans porter un jugement en fonction de la taille et du nombre d'objets détectés. Parce que le but est de porter un jugement simple et de tracer une ligne pour niveler au maximum les erreurs humaines. Nous n'avons pas besoin de ce niveau de précision.

Si vous courez jusqu'à ce point, le nombre d'objets dont les contours ont été détectés et le résultat du jugement seront affichés. Il est enregistré dans le répertoire correspondant.

Résumé

Avec ce script, il est possible de tracer des lignes avec des valeurs numériques spécifiques. Je pense que nous avons pu supprimer la variation dans une certaine mesure.

Cependant, le but est un simple jugement ponctuel Accumuler des données d'image dans une certaine mesure et créer des données d'entraînement basées sur ces données Le but est de porter un jugement en raisonnant.

Après tout, ça fait mal de ne pas pouvoir implémenter l'interface graphique. Comme d'habitude, c'était une tâche que je ne comprenais pas et que je pleurais.

c'est tout.

Recommended Posts

J'ai compté les grains
J'ai compté au revoir mec
J'ai examiné l'arborescence des appareils
J'ai essayé de toucher l'API Qiita
J'ai essayé la bibliothèque changefinder!
J'ai téléchargé la source python
J'ai lu l'article de SHAP
J'ai essayé le tutoriel TensorFlow 1er
Je me suis perdu dans le labyrinthe
J'ai essayé le roman Naro API 2
J'ai étudié le mécanisme de connexion flask!
J'ai participé au tour de qualification ISUCON10!
J'ai essayé le tutoriel TensorFlow 2ème
J'ai étudié à quoi ressemble la lunette
J'ai aimé le tweet avec python. ..
J'ai écrit la file d'attente en Python
J'ai essayé l'API du roman Naruro
J'ai essayé de déplacer le ballon
J'ai essayé d'utiliser l'API checkio
J'ai écrit la pile en Python
J'ai essayé d'estimer la section.
Je ne connais pas l'erreur de valeur
J'ai étudié la superposition de l'arborescence des appareils
J'ai vérifié le montant de la taxe sur les cadeaux
Tutoriel TensorFlow J'ai essayé MNIST 3rd
J'ai demandé à google-home d'effectuer la conférence de beauté
Je veux épingler Spyder à la barre des tâches
J'ai vérifié le contenu du volume du docker
Je veux sortir froidement sur la console
J'ai essayé le serveur asynchrone de Django 3.0
J'ai essayé de résumer la commande umask
J'ai essayé tensorflow pour la première fois
J'ai vérifié les options de copyMakeBorder d'OpenCV
Je veux gérer la rime part1
La structure des dossiers de Flask est résumée
Je suis tombé sur l'API Hatena Keyword
Je veux gérer la rime part3
J'ai essayé l'outil de visualisation OSS, sur-ensemble
Je ne connaissais pas les bases de Python
(Maintenant) j'ai essayé d'analyser le nouveau virus corona (COVID-19)
J'ai essayé de résumer la modélisation graphique.
J'ai essayé de sauvegarder les données récupérées au format CSV!
Tri sélect écrit en C
Je ne peux pas obtenir l'élément dans Selenium!
J'ai essayé d'estimer le rapport de circonférence π de manière probabiliste
[Python] J'ai personnellement résumé la grammaire de base.
J'ai essayé de toucher l'API COTOHA
Python: j'ai essayé le problème du voyageur de commerce
Le modèle de projet Python auquel je pense.
Python "Je ne peux pas atteindre l'endroit qui démange ..."
[Python débutant] J'ai rassemblé les articles que j'ai écrits
J'ai touché à l'outil de préparation de données Paxata
J'ai écrit l'aile coulissante dans la création.
Je veux gérer la rime part2
Je veux gérer la rime part5
Je veux gérer la rime part4
Je ne peux pas installer le package avec pip.
J'ai essayé le framework de test Python Tornado
J'ai essayé d'utiliser l'API BigQuery Storage