Previously posted articles Cell count amnesia
A script that counts the grains made by groping in various ways
I actually implemented it and managed to bring it to a usable level, so I will leave it as a memo.
The degree of dirt is judged by counting the number of particles in the liquid. So-called NAS grade Precise measurement is possible with extremely expensive equipment. (↑ Of course I will not make it if I can do this)
However, the rough judgment is a judgment made by the person who looks at the sample. First of all, the purpose is to draw a line to narrow the range of gabagaba and level it.
Windows10 64bit Jupiter Notebook Python 3.6.10 opencv 3.4.2.17 numpy 1.19.0 matplotlib 3.2.2
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
Basically, image processing using opencv is the main, so use it in this set.
cap_save.ipynb
#Setting the save destination for captured images
dir_path_class00 = 'Specify save directory/01_class00'
dir_path_class0 = 'Specify save directory/01_class01'
#… Below, set the required amount
#Saved image file name
filename1 = 'original_img'#The original image
filename2 = 'processing_img'#Processed image
#Create save dir(No change)
os.makedirs(dir_path_class00,exist_ok=True)
os.makedirs(dir_path_class0,exist_ok=True)
#… Below, set the required amount
#File path join(The original image:1 and processed image:2 Use the file name when saving)
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)
#… Below, set the required amount
#Image save date(* Month * Sun * Hour * Minute)
datename = datetime.now().strftime('%m%d%H%M')
#Name setting when saving an image(When changing, change the relevant part)
name1 = "cell"
name2 = ".jpg "
Strictly speaking, it mainly deals with the old NAS grade, not ISO. For the save destination, we created the save destinations of the old standard grade 00 to grade 12.
I wanted to keep the original image and the processed image (framed), so I set two.
After that, list the scripts required to create the directory and OK.
cap_save.ipynb
#Loading the detected image(The change is at the end ~.jpg only)
img = cv2.imread('Specify the save destination and file name of the image you want to check',1)
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
Even if the captured image part was cv2.VideoCapture ()
, it could be processed without any problem.
(It is necessary to change the processing part such as actual binarization.)
However, I could not recognize it due to the compatibility problem between the USB camera used for the PC I tried to implement and Opencv.
Switched to processing from image selection.
(Is it because of the dedicated firmware? I asked the manufacturer, but I haven't answered yet)
If it is a USB camera on the market, it works and can be processed without any problem, so it is okay. Even with a PC camera (● `・ ω ・) ゞ <ok!
cap_save.ipynb
#Image size
w, h, = (640, 480)
#magnification
mag = 1
#Process 1
img_blur = cv2.GaussianBlur(img_gray,(5,5),1)
#Kernel set
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("The count number is:",answer,"Pieces")
if key == 27:
break
As one of the problems, threshold is specified at the time of contour detection, but if it is done with a fixed value, it is inevitable. There was a problem that chitin and contour were not detected depending on the image. Created to change the threshold value with the track bar.
This area was created by referring to the Udemy course.
After that, it was possible to detect to some extent by erode processing due to the relationship between the lens magnification and the number of pixels of the measuring device. I am adding.
I think that this area can be managed by changing it depending on the detected object.
After that, the contours when contour detection is set to len (contours)
to make it the number of detections.
I had the hardest time here. Speaking of satisfaction, the large outer frame of the image you want to detect has also been counted. To be honest, it's subtle, but I gave up because it's the limit in my mind now.
If you move the track bar like this, you can count from contour detection for the time being.
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("nas grade is:It is equivalent to 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("nas grade is:It is equivalent to 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("nas grade is:It is equivalent to 1.")
… Hereafter, set the required amount.
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("nas grade is:It is equivalent to 12.")
cv2.destroyAllWindows()
Refer to the NAS grade class for the threshold value (set value) that is the basis of the judgment. Strictly speaking, it is impossible to make a precise judgment without making a judgment based on the size and number of detected objects. The purpose is to make a simple judgment and draw a line to level out human errors as much as possible. We do not require that level of accuracy.
If you run up to this point, the number of objects whose contours have been detected and the judgment result will be displayed. It is saved in the corresponding directory.
With this script, it is possible to draw a line with a concrete numerical value. I think we were able to suppress the variation to some extent.
However, the aim is a simple one-shot judgment Accumulate image data to some extent and create learning data based on that data The goal is to make a judgment by reasoning.
After all, it hurts that I couldn't implement GUI. As usual, it was a task that made me cry because I couldn't understand tkinter.
that's all.
Recommended Posts