Willkommen zum 23. Tag des Yuruyuru New Graduate Advent Calendar 2019. Ich bin @NamedPython, ein frisch Absolvent mit einem losen Abschluss: Freude:
Heute geht es um meine versteckte Leistung ** Bilderkennung mit OpenCV **.
Ich hatte mich im Voraus entschlossen, über Bilderkennung zu schreiben, aber es war schwierig, etwas Neues zu finden, deshalb habe ich mein Bestes versucht, es in der Schulklasse zu schreiben, aber ich habe es nirgendwo angeboten ~~ ** Antwortbogen Ich werde hier eine Aufzeichnung der Flächenextraktion hinterlassen **: bleistift2:
Ich sagte, es sei eine Klasse, aber der Name der Klasse lautet ** Programmieranwendung **, und wir arbeiten als Team, um Probleme durch Softwareentwicklung zu lösen, wobei wir das einbeziehen, was wir normalerweise im Unterricht lernen, und die Fähigkeiten unserer Schüler. ist.
Was ist dann das Thema der Problemlösung?
** Erleichtere es dir, deine Prüfungen elektronisch zu bewerten **: bete:
Es war das. Erstens ist es zum Zeitpunkt des elektronischen Scorings noch ziemlich jung, aber wenn Sie die Anforderungen zusammenfassen
Es war so.
Eigentlich ein Jahr vor dieser Klasse,
--Backend API, Webfront @NamedPython --iOS @Taillook
Wir haben das stärkste Team gebildet und große Kritik erhalten. Infolgedessen war die Anzahl der Teammitglieder begrenzt: Stirnrunzeln2:
Trotzdem zog ich @Taillook und einen anderen guten Klassenkameraden zusammen, um ein Team von drei Personen zu bilden.
Mit dem oben erwähnten Team-Team habe ich den Typ gezogen, der iOS schreiben kann.
Da es eine große Sache ist, habe ich ein System mit der folgenden Konfiguration vorgeschlagen, mit dem Sie iOS von allem zu allem fahren können (extrahiert aus der Präsentation der endgültigen Ankündigung). Vielen Dank für die Implementierung rund um iOS, @Taillook.
Ich habe mein Bestes mit Keynote für diese Figur gegeben. Die Schriftarten sind ** M + ** und ** Tsukushi B Maru Gothic **.
findContours
cv2.RETR_TREE
--Diese mit mehr Seiten innerhalb von "ODER" Überspringen Sie den Bereich unter einem bestimmten NiveauZu diesem Zeitpunkt erhielt ich ein aktuelles Antwortblatt zur Überprüfung des Betriebs, aber ich hatte das Gefühl, dass die Rechte, es hierher zu bringen, grau waren, also nutzte ich die Macht von ** Pages craftsman **, um eine Probe zu generieren.
Nun, es ist fast langweilig, also Dawn und der Quellcode. Wir haben eine Docker-Datei wie FROM jjanzic / docker-python3-opencv vorbereitet, damit Sie sie überall entwickeln können. Am Ende war der Bilderkennungsteil übertrieben, weil ich ihn vollständig entwickelt habe.
Der Inhalt von Docker ist wie folgt.
source.py
import os
import cv2
import numpy as np
DIR = os.path.dirname(os.path.abspath(__file__))
image = cv2.imread(f'{DIR}/image/sample_answer_sheet.png')
if image is None:
print("File not found.")
exit()
def write_out(img, name):
cv2.imwrite(f'{DIR}/image/result/{name}.png', img)
def extract_inside(contours, hierarchy, debug=False):
extracted = []
contours_drawed = image.copy()
if debug:
print(f'len: {len(contours)}')
print(hierarchy)
for index in range(len(contours)):
if hierarchy[0, index, 2] != -1 or cv2.contourArea(contours[index]) < 8000:
continue
extracted.append(contours[index])
if debug:
cv2.drawContours(contours_drawed, contours, index, (255, 0, 255), 10)
print(f'{index} : {cv2.contourArea(contours[index])}')
if debug:
write_out(contours_drawed, 'out_contours')
return extracted
width, height = image.shape[:2]
extracted = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)[:, :, 1]
write_out(extracted, 'after_cvt')
ret, thrshld_ex = cv2.threshold(extracted, 0, 255, cv2.THRESH_OTSU)
write_out(thrshld_ex, 'thrshld')
kernel = np.ones((3, 1), np.uint8)
thrshld_ex = cv2.morphologyEx(thrshld_ex, cv2.MORPH_OPEN, kernel)
write_out(thrshld_ex, 'thrshld_ex')
_, contours, hierarchy = cv2.findContours(thrshld_ex, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
inside_contours = extract_inside(contours, hierarchy, True)
print(f'extracted {len(inside_contours)} countours')
clr_img_cp = image.copy()
for circle in inside_contours:
colors = []
av_color = 0
M = cv2.moments(circle)
center_of_circle = (int(M['m10']/M['m00']), int(M['m01']/M['m00']))
cnt = 0
for approx in circle:
if cnt == 20:
break
cv2.circle(clr_img_cp, (approx[0, 0] - 1, approx[0, 1] - 1), 1, (255, 0, 255), 1)
colors.append(image[approx[0, 1] - 1, approx[0, 0] - 1])
cnt += 1
cav = np.mean(colors, axis=0)
cv2.circle(clr_img_cp, center_of_circle, 100, cav, 20)
write_out(clr_img_cp, 'out')
Es sieht so aus, wenn ich das, was ich zuvor in der Erkennungszusammenfassung geschrieben habe, in den Quellcode lege. Nachdem ich so ein Prototyping mit "Python" durchgeführt hatte, portierte ich es auf "Objective-C" und ließ es von @Taillook mit Swift überbrücken.
Die Ergebnisse jedes der vier Prozesse werden veröffentlicht.
extract_s_of_hsv.py
cv2.cvtColor(image, cv2.COLOR_BGR2HSV)[:, :, 1] # 0: H, 1: S, 2: V
Zu diesem Zeitpunkt ist es fast binärisiert. Es ist zu viel.
Geben Sie einfach "cv2.THRESH_OTSU" an. Einfach.
thresold_with_otsu.py
cv2.threshold(extracted, 0, 255, cv2.THRESH_OTSU)
Wenn es ein wenig Rauschen gibt, wenden Sie "Morphology EX" an, um das Rauschen zu entfernen.
OpenCV ist schon erstaunlich. findContours
ist unglaublich. Ich habe die Zeitung vorerst gelesen, aber sie ist zu pervers, um selbst die strukturellen Informationen der Seiten zu erkennen.
find_contours_with_structure.py
_, contours, hierarchy = cv2.findContours(thrshld_ex, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
In "Hierarchie" wird ** gespeichert, welche Indexseite in "Konturen" ** neben der Indexseite ** oder ** enthalten ist **. Es ist zu viel.
Die Seiten werden durch eine Reihe von Punkten dargestellt und sind lila gezeichnet.
Dies ist ein Push. Vielen Dank an numpy
, dass es so einfach ist, die Farben zu mitteln.
sampling_color_and_averaging_and_plotting.py
clr_img_cp = image.copy()
for circle in inside_contours:
colors = []
av_color = 0
M = cv2.moments(circle)
center_of_circle = (int(M['m10']/M['m00']), int(M['m01']/M['m00']))
cnt = 0
for approx in circle:
if cnt == 20:
break
cv2.circle(clr_img_cp, (approx[0, 0] - 1, approx[0, 1] - 1), 1, (255, 0, 255), 1)
colors.append(image[approx[0, 1] - 1, approx[0, 0] - 1])
cnt += 1
cav = np.mean(colors, axis=0)
cv2.circle(clr_img_cp, center_of_circle, 100, cav, 20)
Der Mittelpunkt der Figur wird bestimmt und dort ein Kreis mit der Durchschnittsfarbe gezeichnet. (Wenn Sie sich dieses Bild genau ansehen, sind die Zielpixel von 20 Samples lila gefärbt.) Es fühlt sich gut an mit fast der gleichen Farbe wie die Seite.
Also habe ich hier einen Gedenkgottesdienst für das Bildverarbeitungsprogramm gemacht, das ich als Student gemacht habe: Sarg:
Es war ein Spiegelbild aus meiner Sicht, aber ich hoffe, Sie können dies lesen und die Möglichkeit von "Python" + "OpenCV" spüren.
Die einzige Einschränkung ist, dass "OpenCV" verwendet werden kann, indem aus vielen Fällen gelernt wird, ohne die Theorie zu kennen, aber ich denke, dass die Theorie der erste Schritt ist, um den kürzesten Weg für die Anwendung von Mitteln zur Lösung von Problemen abzuleiten. Daher ist ** Informationstechnik wichtig **. Ich habe nur die Last-Minute-Theorie, weil ich leicht und leicht war.
Das Folgende kann jedoch mit Sicherheit gesagt werden.
Python
+ OpenCV
ist einfach zu machennumpy
darüber. Eigentlich habe ich "OpenCV" von "Rust" ausprobiert, bevor ich diesen Artikel geschrieben habe, aber es war nicht gut im Vergleich zur Benutzerfreundlichkeit von "Python" + "OpenCV". Nun, ich bin es nicht gewohnt, "Rust" zu implementieren, daher ist es vielleicht nicht hilfreich, aber: yum:
Es ist "Python", ist es nicht langsam? Es scheint eine Geschichte zu geben, aber ohne Zeichnung geht es um ** 0,3 [Sek] **. Es ist nur eine "C-Bindung". Toll. Selbst auf der Fahrrad-Shopping-Site cyma-cyma-, an der ich beteiligt bin, habe ich irgendwie die Motivation zur Bilderkennung gewonnen, deshalb möchte ich meine Stärke demonstrieren.
@shimura_atsushi hat 2 Artikel in Ateam cyma Adventskalender 2019 geschrieben. Wenn Sie also interessiert sind, bitte.
Yuruyuru New Graduate 1. Klasse Adventskalender 2019, wie war dein 23. Tag?
Am 24. Tag ist der Front-End-Ingenieur @ cheez921 an der Reihe, der auch das Back-End versteht. Duell, Standby!
Gutes ** Weihnachten **, gutes ** Jahresende **, gutes ** neues Jahr **, gutes ** Bilderkennung **.
Recommended Posts