Je suis un débutant en langue Go. Mon habitat habituel est JS / TS + Java, mais j'essaie le langage Go à partir de cette année parce que je veux être meilleur dans le traitement des langages côté serveur. La raison de ce défi est «des activités modernes, multi-threadées et liées aux conteneurs».
Après tout, le style de faire quelque chose et d'apprendre ça me convient, donc cette fois avec le thème du "traitement d'image", un outil qui peut être utilisé à la fois comme CLI et comme API yellow-high5 / pictar J'ai fait (: //github.com/yellow-high5/pictar). Le traitement d'image n'est pas aussi avancé que l'utilisation de CNN pour la reconnaissance d'image.
Tout d'abord, j'ai brièvement vérifié le fonctionnement du paquet d'images standard Go.
Le point de coordonnées Point est composé de X et Y de int, et la zone rectangulaire Rectangle est composée de Min et Max de Point.
--Alpha ... Transparence --CMYK ... Comment exprimer les couleurs affichées en cyan, magenta, jaune et noir (Key Plate) --RGB ... Comment exprimer les couleurs affichées en rouge, vert et bleu --Gray .. Si l'échelle de gris est RVB, les trois valeurs seront identiques.
image.NRGBA Dans cette structure, l'image est traitée comme un tableau unidimensionnel ** qui répète ** Rouge, Vert, Bleu, Alpha avec «Pix». «Stride» signifie ** la taille d'une ligne horizontale de l'image **.
Les personnes qui ne sont pas spécialisées dans le traitement d'images ne peuvent pas comprendre les formules difficiles, nous utilisons donc des bibliothèques. Cette fois, nous utiliserons désintégration / imagerie. La source elle-même est également concise et facile à lire. Les fonctions peuvent être les suivantes.
--adjust ... Échelle de gris, inversion, contraste, saturation --convolution ... compression 3x3, compression 5x5 --effets ... Flou, net --matrix (histogramme normalisé) ... Exprime la luminosité dans un tableau de 256 (16x16) --resize ... redimensionner, recadrer, mettre à l'échelle (ajustement), vignette --transformer ... Retourner, Transposer, Faire pivoter
--io ... Lire l'image, ouvrir l'image, écrire l'image, enregistrer l'image, lire l'orientation de l'image (drapeau EXIF), convertir, modifier --scanner ... Lit la zone spécifiée par le rectangle --tools ... Créer une nouvelle image, copier, coller, transparente --utils ... parallèle, autres utilitaires
Extra: Glossaire du traitement d'image
J'ai senti qu'il était nécessaire de comprendre certains termes de traitement d'image pour en faire un outil, donc j'organiserai mes connaissances.
- Espace colorimétrique HSV ... Teinte, Saturation Un espace de composants composé de (Saturation) et de luminosité (Valeur). Il semble être plus intuitif et facile à comprendre que l'espace RVB, qui est déterminé par le mélange de couleurs primaires.
- Espace colorimétrique HLS ... Teinte, Luminosité ( Un espace de composants composé de trois composants: Luminosité et Saturation Similaire à l'espace HSV.
- Saturation ... Image supérieure plus sombre, couleur d'image inférieure Image qui s'amincit.
- [Contraste](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) ... Lorsqu'elle est élevée, la différence de luminosité de l'image est nette, et lorsqu'elle est faible, l'image est floue.
- Luminosité ... Image qui devient blanchâtre lorsqu'elle est haute et noirâtre lorsqu'elle est basse.
- Correction gamma ... proportion simple Une méthode de correction RVB qui correspond aux caractéristiques visuelles humaines, pas à la relation.
- [Flou gaussien](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) ... La valeur sigma correspond à la quantité de flou.
- [Fonction Sigmaid](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) ... En Deep Learning, c'était une fonction familière de calculer "la probabilité que le nombre écrit dans cette image soit 1", mais en traitement d'image, contraste Il semble qu'il sert à s'ajuster.
désintégration / imagerie utilise un traitement parallèle lors du traitement des images. Cela semble permettre un traitement relativement rapide. Certaines personnes mesurent la vitesse de traitement de l'image, donc si vous voulez en savoir plus à ce sujet, je pense que vous devriez vous y référer.
Alors, quel type de traitement parallèle est effectué par goroutine dans cette bibliothèque? L'indice était dans la fonction parallèle ci-dessous.
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 ** est le nombre d'opérations à effectuer. Dans le cas du traitement d'image, cela correspond au nombre de pixels et à une ligne horizontale d'images. ** procs ** est le nombre de processus à exécuter simultanément. (La valeur par défaut est le nombre de processeurs. Si vous spécifiez le nombre de goroutines à traiter simultanément avec ** limit **, la limite est adoptée.)
Le nombre de valeurs d'entrée est envoyé au canal, et le nombre de procs de goroutine reçoit la valeur d'entrée du canal et la traite en parallèle avec la fonction transmise.
Vous trouverez ci-dessous un tableau montrant comment imaging.FlipH (le processus consistant à inverser la gauche et la droite d'une image) traite en parallèle et la produit. J'ai essayé de dessiner une image.
Le code qui réalise l'image ci-dessus
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))
//Faites travailler en parallèle autant que la hauteur de l'image
parallel(0, dstH, func(ys <-chan int) {
//Inverser le groupe de pixels pour une ligne
for dstY := range ys {
//Placez chaque pixel à l'endroit au moment de l'inversion
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
}
Enveloppez ces bibliothèques et créez une CLI en utilisant cobra. Tout d'abord, lors de la conception d'une CLI, identifions les sous-commandes et les options à exécuter par cette commande. Vous devriez également envisager de rendre les options applicables globalement.
Fondamentalement, il est créé avec le modèle de générateur dans le modèle de conception. En tant que référence pour le design, il est également traité dans les réalisations de cobra, mais j'ai essayé d'imiter Hugo.
Dans Hugo, lors de la définition d'une sous-commande, définissez-la comme suit.
Lors de la définition d'une sous-commande appelée "hoge"
package commands
//La structure définit les options
type hogeCmd struct {
*baseBuilderCmd
/*Options d'écriture*/
...
}
//Retour des options dans Command Builder
func (b *commandsBuilder) newHogeCmd() *hogeCmd {
//Définir une interface vide facultative
cc := &hogeCmd{}
//Définition de commande avec cobra
cmd := &cobra.Command{
Use: "hoge",
Short: "Short Description",
Long: `Long Description`,
RunE: func(cmd *cobra.Command, args []string) error {...},
}
//S'il existe une sous-sous-commande, définissez-la
cmd.AddCommand(...)
//Définir les options comme indicateurs
cmd.Flags().StringVarp(...)
//Inscrire le constructeur
cc.baseBuilderCmd = b.newBuilderBasicCmd(cmd)
return cc
}
Il sera complété en ajoutant les sous-commandes nécessaires au générateur de commandes. Vous pouvez avoir une bonne idée de la conception du générateur de commandes en consultant ce fichier (https://github.com/gohugoio/hugo/blob/master/commands/commands.go).
Lors du POST d'une image avec http, j'ai créé une fonction pour traiter l'image et la sauvegarder dans le stockage d'objets (S3 cette fois). Le contenu de traitement est un mécanisme à lire à partir du fichier de paramètres. Il a été implémenté en supposant les fonctions qui peuvent être utilisées pour enregistrer des images de profil et créer des vignettes dans l'application.
J'ai lu Gin's GoDoc, qui est un framework Web créé par Go, et j'ai fait une image approximative. C'est un peu cassé, mais si vous le simplifiez, cela ressemble à ceci. Il semble que vous créez une logique qui renvoie une réponse HTTP à partir d'une requête HTTP en connectant les processus avec HandlerFunc (middleware).
↓ Image
gin.Default ()
ou gin.New ()
)L'expression du traitement HTTP dans une chaîne middleware est très similaire à Express dans Node.js.
J'ai déraillé, mais revenons au processus de téléchargement de fichiers. Le flux de traitement est d'environ 3 étapes.
J'ai fait référence à ce qui suit pour télécharger des fichiers vers Go. Veuillez consulter Amazon Web Services --Go SDK pour les paramètres détaillés.
Télécharger des fichiers vers S3 en langage Go (golang) \ | Developers.IO
En utilisant viper, il est possible d'accéder au fichier de configuration (config.json etc.) de paramètres détaillés tels que les paramètres de connexion de stockage d'objets et de sauvegarder le nom des images. est.
En enquêtant, j'ai trouvé un serveur de traitement d'image fabriqué par Go, qui est également introduit dans les réalisations de Gin.
C'est mieux conçu qu'un outil pour les débutants comme moi. J'ai décidé de l'utiliser sans hésitation lors de la mise en œuvre du service. Si vous trouvez une solution à ce que vous essayiez de faire, vous en apprendrez plus.
Pour le moment, je sentais que mon défi était de pouvoir maîtriser les packages standards de Go et le traitement parallèle. Les forfaits Go ont de bonnes perspectives et je ne suis pas trop fatigué donc je pense pouvoir m'entraîner pendant un moment.
Recommended Posts