Ich habe eine Art einfaches Bildverarbeitungswerkzeug in der Sprache Go erstellt.

Ich bin ein Anfänger in Go-Sprache. Mein üblicher Lebensraum ist JS / TS + Java, aber ich versuche die Go-Sprache aus diesem Jahr, weil ich serverseitige Sprachen besser verarbeiten möchte. Der Grund für die Herausforderung sind "moderne Aktivitäten mit mehreren Threads und Containern".

Schließlich passt der Stil, etwas zu machen und es zu lernen, zu mir, diesmal also mit dem Thema "Bildverarbeitung", einem Tool, das sowohl als CLI als auch als API verwendet werden kann gelb-hoch5 / pictar Ich habe (: //github.com/yellow-high5/pictar) gemacht. Die Bildverarbeitung ist nicht so fortgeschritten wie die Verwendung von CNN zur Bilderkennung.

Gehen Sie zum Standard-Image-Paket

Zuerst habe ich kurz überprüft, wie das Go Standard Image Package funktioniert.

Point,Rectangle

Der Koordinatenpunktpunkt besteht aus X und Y von int, und das rechteckige Rechteck besteht aus Min und Max von Punkt.

image.png

Color

--Alpha ... Transparenz --CMYK ... Wie man die Farben in Cyan, Magenta, Gelb und Schwarz ausdrückt (Schlüsselplatte) --RGB ... So drücken Sie die Farben in Rot, Grün und Blau aus --Grau .. Wenn die Graustufe RGB ist, sind alle drei Werte gleich.

image.NRGBA In dieser Struktur wird das Bild als eindimensionales Array ** behandelt, das ** Rot, Grün, Blau, Alpha mit "Pix" wiederholt. Stride steht für ** die Größe einer horizontalen Bildreihe **.

image.png

Lesen Sie die Imaging-Bibliothek

Leute, die nicht auf Bildverarbeitung spezialisiert sind, können schwierige Formeln nicht verstehen, deshalb verwenden wir Bibliotheken. Dieses Mal verwenden wir Desintegration / Imaging. Die Quelle selbst ist ebenfalls übersichtlich und leicht zu lesen. Die Funktionen können wie folgt sein.

Bildverarbeitung

--adjust ... Graustufen, Inversion, Kontrast, Sättigung --Faltung ... 3x3 Komprimierung, 5x5 Komprimierung

Hilfsdienstprogramm

--io ... Bild lesen, Bild öffnen, Bild schreiben, Bild speichern, Bildorientierung lesen (EXIF-Flag), konvertieren, ändern --scanner ... Liest den durch das Rechteck angegebenen Bereich --tools ... Neues Bild erstellen, kopieren, einfügen, transparent --utils ... parallel, andere Dienstprogramme

Extra: Glossar der Bildverarbeitung

Ich hatte das Gefühl, dass es notwendig ist, einige Bildverarbeitungsbegriffe zu verstehen, um ein Werkzeug zu erstellen, damit ich mein Wissen organisieren kann.

  • HSV-Farbraum ... Farbton, Sättigung Ein Komponentenraum bestehend aus (Sättigung) und Helligkeit (Wert). Es scheint intuitiver und leichter zu verstehen als der RGB-Raum, der durch die Mischung der Primärfarben bestimmt wird.
  • HLS-Farbraum ... Farbton, Helligkeit ( Ein Komponentenraum, der aus drei Komponenten besteht: Helligkeit und Sättigung. Ähnlich wie im HSV-Raum.
  • Sättigung ... Höheres Bild dunkler, niedrigere Bildfarbe Bild, das dünner wird.
  • [Kontrast](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%88%E3%83%A9%E3%82%B9%E3 % 83% 88 #% E5% 86% 99% E7% 9C% 9F% E6% A9% 9F% E3% 80% 81% E6% 98% A0% E5% 83% 8F% E6% A9% 9F% E5% 99% A8) ... Wenn es hoch ist, ist der Helligkeitsunterschied des Bildes deutlich, und wenn es niedrig ist, ist das Bild vage.
  • Helligkeit ... Bild, das im hohen Zustand weißlich und im niedrigen Bereich schwärzlich wird.
  • Gammakorrektur ... unkompliziertes Verhältnis Eine RGB-Korrekturmethode, die den visuellen Eigenschaften des Menschen entspricht, nicht der Beziehung.
  • [Gaußsche Unschärfe](https://ja.wikipedia.org/wiki/%E3%82%AC%E3%82%A6%E3%82%B7%E3%82%A2%E3%83%B3% E3% 81% BC% E3% 81% 8B% E3% 81% 97) ... Der Sigma-Wert entspricht dem Ausmaß der Unschärfe.
  • [Sigmaid-Funktion](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%B0%E3%83%A2%E3%82%A4%E3%83%89% E9% 96% A2% E6% 95% B0) ... Beim Deep Learning war es eine bekannte Funktion, "die Wahrscheinlichkeit zu berechnen, dass die in dieses Bild geschriebene Zahl 1 ist", bei der Bildverarbeitung jedoch den Kontrast Es scheint, dass es verwendet wird, um anzupassen.

Parallelverarbeitung

Desintegration / Imaging verwendet bei der Verarbeitung von Bildern die Parallelverarbeitung. Dies scheint eine relativ schnelle Verarbeitung zu ermöglichen. Einige Leute messen die Geschwindigkeit der Bildverarbeitung. Wenn Sie also mehr darüber erfahren möchten, sollten Sie sich darauf beziehen.

Vergleich der Bildverarbeitungsleistung in OpenCV, GoCV, Go-Sprache - ZOZO Technologies TECH BLOG

Welche Art von Parallelverarbeitung wird von Goroutine in dieser Bibliothek durchgeführt? Der Hinweis war in der parallelen Funktion unten.

imaging/utils.go


// parallel processes the data in separate goroutines.
func parallel(start, stop int, fn func(<-chan int)) {
	count := stop - start
	if count < 1 {
		return
	}

	procs := runtime.GOMAXPROCS(0)
	limit := int(atomic.LoadInt64(&maxProcs))
	if procs > limit && limit > 0 {
		procs = limit
	}
	if procs > count {
		procs = count
	}

	c := make(chan int, count)
	for i := start; i < stop; i++ {
		c <- i
	}
	close(c)

	var wg sync.WaitGroup
	for i := 0; i < procs; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			fn(c)
		}()
	}
	wg.Wait()
}

** count ** ist die Anzahl der Operationen, die ausgeführt werden müssen. Bei der Bildverarbeitung entspricht dies der Anzahl der Pixel und einer horizontalen Bildreihe. ** procs ** ist die Anzahl der Prozesse, die gleichzeitig ausgeführt werden sollen. (Die Standardeinstellung ist die Anzahl der CPUs. Wenn Sie die Anzahl der Goroutinen angeben, die gleichzeitig mit ** limit ** verarbeitet werden sollen, wird das Limit übernommen.)

Die Anzahl der Eingabewerte wird an den Kanal gesendet, und die Prozessnummer der Goroutine empfängt den Eingabewert vom Kanal und verarbeitet ihn parallel zur übergebenen Funktion.

Die folgende Tabelle zeigt, wie Imaging.FlipH (der Vorgang des Invertierens von links und rechts eines Bildes) parallel verarbeitet und ausgegeben wird. Ich habe versucht, ein Bild zu zeichnen.

image.png

Der Code, der das obige Bild realisiert


func FlipH(img image.Image) *image.NRGBA {
	src := newScanner(img)
	dstW := src.w
	dstH := src.h
	rowSize := dstW * 4
	dst := image.NewNRGBA(image.Rect(0, 0, dstW, dstH))
    //Lassen Sie die Parallelverarbeitung so hoch wie die Höhe des Bildes arbeiten
	parallel(0, dstH, func(ys <-chan int) {
        //Invertieren Sie die Pixelgruppe für eine Zeile
		for dstY := range ys {
            //Platzieren Sie jedes Pixel zum Zeitpunkt der Inversion an der Stelle
			i := dstY * dst.Stride
			srcY := dstY
			src.scan(0, srcY, src.w, srcY+1, dst.Pix[i:i+rowSize])
			reverse(dst.Pix[i : i+rowSize])
		}
	})
	return dst
}

CLI-Tool mit Kobra

Wickeln Sie diese Bibliotheken ein und erstellen Sie eine CLI mit cobra. Lassen Sie uns beim Entwerfen einer CLI zunächst die Unterbefehle und Optionen identifizieren, die von diesem Befehl ausgeführt werden sollen. Es ist auch eine gute Idee, die Optionen global anwendbar zu machen.

Grundsätzlich wird es mit dem Builder-Muster im Entwurfsmuster erstellt. Als Referenz für das Design wird es auch in den Errungenschaften der Kobra behandelt, aber ich habe versucht, [Hugo] nachzuahmen (https://gohugo.io/).

hugo/commands GitHub

Wenn Sie in Hugo einen Unterbefehl definieren, definieren Sie ihn wie folgt.

Bei der Definition eines Unterbefehls namens "hoge"


package commands


//Die Struktur definiert Optionen
type hogeCmd struct {
  *baseBuilderCmd

  /*Schreiboptionen*/
  ...
}

//Rückgabe von Optionen in Command Builder
func (b *commandsBuilder) newHogeCmd() *hogeCmd {
  //Definieren Sie eine optionale leere Schnittstelle
  cc := &hogeCmd{}
  
  //Befehlsdefinition mit Kobra
  cmd := &cobra.Command{
		Use:   "hoge",
		Short: "Short Description",
		Long: `Long Description`,
    RunE: func(cmd *cobra.Command, args []string) error {...},
	}
  //Wenn es einen Sub-Sub-Befehl gibt, definieren Sie ihn
  cmd.AddCommand(...)
  
  //Definieren Sie Optionen als Flags
  cmd.Flags().StringVarp(...)
  
  //Registrieren Sie den Builder
  cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
  
  return cc
}

Zum Abschluss werden dem Befehlsgenerator die erforderlichen Unterbefehle hinzugefügt. In dieser Datei (https://github.com/gohugoio/hugo/blob/master/commands/commands.go) erhalten Sie eine bessere Vorstellung vom Design des Befehlsgenerators.

Bildverarbeitungsserver mit Gin

Beim POSTEN eines Bildes mit http habe ich eine Funktion erstellt, um das Bild zu verarbeiten und im Objektspeicher zu speichern (diesmal S3). Der Verarbeitungsinhalt ist ein Mechanismus zum Lesen aus der Einstellungsdatei. Es wurde unter der Annahme implementiert, dass Funktionen zum Registrieren von Profilbildern und zum Erstellen von Miniaturansichten in der App verwendet werden können.

Gins Logik

Ich habe Gins GoDoc gelesen, ein Web-Framework von Go, und ein grobes Bild gemacht. Es ist ziemlich kaputt, aber wenn Sie es vereinfachen, sieht es so aus. Es scheint, dass Sie eine Logik erstellen, die eine HTTP-Antwort von einer HTTP-Anforderung zurückgibt, indem Sie die Prozesse mit HandlerFunc (Middleware) verbinden.

↓ Bild image.png

Das Ausdrücken der HTTP-Verarbeitung in einer Middleware-Kette ist Express in Node.js sehr ähnlich.

Datei-Upload nach S3

Ich habe entgleist, aber kehren wir zum Hochladen von Dateien zurück. Der Verarbeitungsablauf beträgt ca. 3 Schritte.

  1. Lesen Sie das Image von dem im HTTP-Anforderungshauptteil angegebenen Client und speichern Sie es im Dateisystem des Servers.
  2. Verarbeiten Sie die gelesene Datei mit der Imaging-Bibliothek.
  3. Laden Sie die verarbeitete Bilddatei in S3 hoch und geben Sie den Erfolgsstatus zurück.

Ich habe auf Folgendes verwiesen, um Dateien nach Go hochzuladen. Ausführliche Einstellungen finden Sie unter Amazon Web Services - Go SDK.

Dateien in der Go-Sprache (golang) in S3 hochladen \ | Developers.IO

Wenn Sie viper verwenden, können Sie in die Einstellungsdatei (config.json usw.) mit detaillierten Einstellungen wie den Verbindungseinstellungen des Objektspeichers gehen und den Namen der Bilder speichern. ist.

Zusammenfassung

Während der Untersuchung fand ich einen Bildverarbeitungsserver von Go, der auch in Gins Errungenschaften vorgestellt wird.

Dies ist besser als ein Werkzeug für Anfänger wie mich. Ich habe mich entschlossen, dies ohne zu zögern zu verwenden, wenn ich es mit der Service-Implementierung mache. Wenn Sie eine Lösung für das finden, was Sie versucht haben, werden Sie mehr erfahren.

Vorerst hatte ich das Gefühl, dass meine Herausforderung darin bestand, die Standardpakete und die Parallelverarbeitung von Go zu beherrschen. Go-Pakete haben gute Aussichten und ich bin nicht zu müde, damit ich eine Weile trainieren kann.

Recommended Posts

Ich habe eine Art einfaches Bildverarbeitungswerkzeug in der Sprache Go erstellt.
Ich habe ein CLI-Tool in der Sprache Go geschrieben, um Qiitas Tag-Feed in CLI anzuzeigen
Ich habe ein einfaches Tippspiel mit tkinter of Python gemacht
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 1)
Ich habe ein Punktbild des Bildes von Irasutoya gemacht. (Teil 2)
Made gomi, ein Papierkorb-Tool für rm in Go-Sprache
[Python] Ich habe einen Bildbetrachter mit einer einfachen Sortierfunktion erstellt.
Ich habe ein Pay-Management-Programm in Python erstellt!
Ich habe ein automatisches Stempelwerkzeug für den Browser erstellt.
Ich habe ein Passwort-Tool in Python erstellt.
Ich habe mit Python einen einfachen Blackjack gemacht
Ich habe ein Programm erstellt, um die Größe einer Datei mit Python zu überprüfen
Ich habe einen Fehler beim Abrufen der Hierarchie mit MultiIndex von Pandas gemacht
Ich habe go Sprache für API und die minimale Konfiguration der Reaktion für die Front gemacht
Ich habe ein Tool erstellt, um die Ausführungszeit von cron zu schätzen (+ PyPI-Debüt)
Ich habe ein nützliches Tool für Digital Ocean erstellt
Ich habe ein Tool erstellt, um Slack über Connpass-Ereignisse zu informieren, und es zu Terraform gemacht
[Python] [Verarbeitung natürlicher Sprache] Ich habe Deep Learning ausprobiert (auf Japanisch von Grund auf neu erstellt)
Ich habe einen Appdo-Befehl erstellt, um Befehle im Kontext der App auszuführen
Ich habe ein Router-Konfigurationssammlungstool Config Collecor erstellt
Ich habe ein Tool erstellt, um Hy nativ zu kompilieren
Ich habe ein Modul in C-Sprache erstellt, das von Python geladene Bilder filtert
Ich habe ein Tool zum automatischen Sichern der Metadaten der Salesforce-Organisation erstellt
Ich habe ein Tool erstellt, um neue Artikel zu erhalten
Ich habe einen einfachen RSS-Reader ~ C Edition ~ gemacht
Ich habe ein Caesar-Kryptografieprogramm in Python erstellt.
Unerträgliche Aufmerksamkeitsmangel bei der Verarbeitung natürlicher Sprache
Nachdem ich 2015 100 Sprachverarbeitungsklopfen gemacht hatte, bekam ich viele grundlegende Python-Fähigkeiten, Kapitel 1
Bildverarbeitung mit Python (ich habe versucht, es in 0 und 1 Mosaikkunst zu binarisieren)
100 Klopfen bei der Bildverarbeitung !! (021-030) Ich möchte eine Pause machen ...
Liste der Orte, auf die ich beim Hochladen von Bildern aus Django gestoßen bin
Lassen Sie uns Chat-Benutzerverwaltungstool gemacht
Ich habe ein Reinigungstool für Google Container Registry erstellt
Ich habe ein Schwellenwertänderungsfeld für Peppers Dialog erstellt
Ich habe ein Skript erstellt, um ein Snippet in README.md einzufügen
Leistungsüberprüfung der Datenvorverarbeitung in der Verarbeitung natürlicher Sprache
Erstellen Sie einen Webserver in der Sprache Go (net / http) (1)
Zeigen Sie ein Histogramm der Bildhelligkeitswerte in Python an
Ich habe ein Tool zur Erzeugung sich wiederholender Textdaten "rpttxt" erstellt.
Ich habe Bugspots verwendet, ein Tool zur Fehlervorhersage in Quecksilber
〇✕ Ich habe ein Spiel gemacht
Funktionen der Go-Sprache
Ich habe ein Tool erstellt, um die Antwortlinks von OpenAI Gym auf einmal zu erhalten
Ich habe eine Funktion zum Trimmen des Bildes von Python openCV erstellt. Verwenden Sie sie daher bitte.
Ich habe ein Tool erstellt, um automatisch ein einfaches ER-Diagramm aus der Anweisung CREATE TABLE zu generieren
[Verarbeitung natürlicher Sprache] Ich habe versucht, die Bemerkungen jedes Mitglieds in der Slack-Community zu visualisieren
Arten der Vorverarbeitung in der Verarbeitung natürlicher Sprache und ihre Leistungsfähigkeit
Ich habe einen schnellen Feed-Reader mit Feedparser in Python erstellt
Ich habe eine einfache Buch-App mit Python + Flask ~ Introduction ~ erstellt
Ich habe ein Numer0n-Kampfspiel in Java gemacht (ich habe auch KI gemacht)
Ich habe ein Tool erstellt, um eine Wortwolke aus Wikipedia zu erstellen