Möchte man sein Machine Learning Model eigenständig trainieren, ist es teilweise hilfreich einige Bilder zur Verfügung zu haben. Lass uns einfach mal davon ausgehen, dass unser Neuronales Netzwerk eine Katze erkennen soll. So sollten wir tausende Bilder von Katzen aus dem Netz laden, um unser Model erfolgreich trainieren zu können. Die Katzen wären die positiven Ergebnisse und z.B. Hunde, Häuser, Kühe die negativen. Anhand dieser Konstellation zwischen positiven und negativen Bildern, kann unser Netzwerk die Katze klassifizieren. Dazu habe ich ein Python Skript geschrieben. Je nachdem was die Keywörter sind, sucht es passende Bilder. Die Bilder werden heruntergeladen, verkleinert und in Graustufe gespeichert. Ich habe jeweils ein Skript für die negativen Bilder und eins für die positiven. Die beiden Skripte unterscheiden sich nur in dem Pfad, wo die Bilder später abgelegt sind. Selbstverständlich können die Skripte auch für andere Verwendungszwecke dazu gezogen werden. Ich benutze das Package iCrawler, welches mir Methoden für die gängigen Suchmaschinen, wie Bing, Google, etc., zur Verfügung stellt.
pip install icrawler
Weiterhin verwende ich cv2, um das Bild im nachhinein zu verkleinern und es als Graustufe zu speichern. In diesem Blogbeitrag habe ich die Installation beschrieben: OpenCV auf dem Raspberry Pi installieren.
Der Code
Kommen wir nun zum eigentlichen Code. Dieser empfängt Parameter entgegen, die wir beim Aufruf übergeben. Für jedes Keyword, führt es ein Crawl aus, der nach den Bildern in der angegebenen Suchmaschine sucht. Die Bilder ermittelt iCrawler anhand bestimmter Werte. Zum einen ist das der Dateityp, der hier .jpg oder .png ist. Wir definieren ein Filter der nach der Größe ‚large‘ und der Lizenz ‚commercial, modify‘ gegenprüft. Nachdem die Bilder im Ordner gespeichert sind, geht der nächste Part über die Bilder, verkleinert und ergraut diese.
from icrawler.builtin import BingImageCrawler import os import cv2 import argparse # Create Argument Parser ap = argparse.ArgumentParser() ap.add_argument("-k", "--keyword", required=True,help="keywords of the images to download separated by ',' ") ap.add_argument("-m", "--max-number", required=True,help="declare max number") args = vars(ap.parse_args()) # directory of loaded images directory = 'img/pos/' # keyword to search for keyword=args["keyword"].split(',') # allowed filetypes resize_file_types = ("jpg","png") #Initiate bing_crawler and define threads + storage bing_crawler = BingImageCrawler( feeder_threads=1, parser_threads=2, downloader_threads=4, storage={'root_dir':directory} ) #create filter filters = dict( size='large', license='commercial,modify', ) # crawl bing for each keyword for key in keyword: bing_crawler.crawl(keyword=key,filters=filters,max_num=int(args['max_number']),file_idx_offset=0) # grayscale + resize each image found message = "** resize and grayscale downloaded Image/s ({0})**".format(len(os.listdir(directory))) print() print("*"*int(len(message))) print("*"*int(len(message))) print(message) print("*"*int(len(message))) print("*"*int(len(message))) # for each file in directory for filename in os.listdir(directory): # if file is a picture if filename.endswith(resize_file_types): print("resize and grayscale {0}{1}".format(directory,filename)) # make grayscale img = cv2.imread(directory + filename, cv2.IMREAD_GRAYSCALE) # resize image resized_img = cv2.resize(img, (100,100)) # write new picture cv2.imwrite(directory + filename, resized_img) message = "** found {0} Image/s **".format(len(os.listdir(directory))) print() print("*"*int(len(message))) print("*"*int(len(message))) print(message) print("*"*int(len(message))) print("*"*int(len(message)))
Um auf das Beispiel von oben mit den Katzen zurückzukommen. Der Aufruf sieht wie folgt aus:
python pos_img_crawler.py -k katze -m 1000
Und natürlich die negativen Bilder(Haus, Hund, Kuh). Achtet bitte darauf, dass es sich um zwei unterschiedliche Dateien handelt :
python neg_img_crawler.py -k haus,hund,kuh -m 1000