Help us understand the problem. What is going on with this article?

GoCVを用いてGoで集めた画像で壁紙を作ってみました

概要

集めた画像からGo言語を用いて集めた画像から壁紙を作ってみようと思います。ライブラリとしてはGoCVを利用してみました。
以前、同じことをPythonとJuliaで行いました。

実際にコードを書いてみた私的な感想としては、PythonやJuliaで書いたほうが書きやすかったですね...( *´艸`)

実行環境

  • Windows10 Pro
  • go version go1.13.1 windows/amd64
  • OpenCV 4.1.2
  • GoCV

GoCVのインストール方法

画像を操作するためにGoCVを利用するために事前に準備する必要があります。以下の公式サイトのインストール手順に従っていけばインストールできると思います。

注意点としては上記のセットアップの途中で再起動しないと認識されない場合がありました。

ソースコード

パッケージのインポート

package main

import (
    "fmt"
    "gocv.io/x/gocv"
    "image"
    "image/jpeg"
    "os"
    "path/filepath"
    "math/rand"
    "log"
    "strconv"
    "time"
)

指定した範囲で被りなしの整数を生成するための関数

以下のリンクを参考にさせていただきました。
- min-maxの範囲からn個の整数をランダム抽出する方法(ただし重複は含まない)

func allKeys(m map[int]bool) []int {
    i := 0
    result := make([]int, len(m))
    for key, _ := range m {
        result[i] = key
        i++
    }
    return result
}

func pickup(min int, max int, num int) []int {
    numRange := max - min

    selected := make(map[int]bool)
    rand.Seed(time.Now().UnixNano())
    for counter := 0; counter < num; {
        n := rand.Intn(numRange) + min
        if selected[n] == false {
            selected[n] = true
            counter++
        }
    }
    keys := allKeys(selected)

    // sort.Sort(sort.IntSlice(keys))
    return keys
}

実際の処理

func main(){

    startT1 := time.Now()
    datapath := "../../../100.data/1.Input/photo/fankiru/*.jpg"
    dirpath := "../../../100.data/2.Output/go/photo/fankiru/"
    files, err := filepath.Glob(datapath)
    if err != nil {
        log.Fatal(err)
    }

    name := "fankiru"
    sizeHeight := 3024
    sizeWidth := 4032
    rh := 5
    rw := 9

    rowSize := int(float64(sizeHeight) * float64(rh))
    colSize := int(float64(sizeWidth) * float64(rw))
    outputImg := gocv.NewMatWithSize(rowSize, colSize, gocv.MatTypeCV8UC3)

    for count := 1; count <= 100; count++ {
        selectnums := pickup(0, len(files)-1, rh*rw)
        selectnum := 0
        for row := 0; row <= sizeHeight * rh - sizeHeight; row += sizeHeight {
            for col := 0; col <= sizeWidth * rw - sizeWidth; col += sizeWidth {
                img := gocv.IMRead(files[selectnums[selectnum]], gocv.IMReadColor)
                if img.Empty() {
                    fmt.Printf("cannot read image \n")
                    return
                }
                defer img.Close()

                rect := outputImg.Region(image.Rectangle{ 
                    image.Point{X: col, Y: row}, 
                    image.Point{X: col + sizeWidth, Y: row + sizeHeight},
                })
                img.CopyTo(&rect)
                selectnum++
            }
        }

        image, err := outputImg.ToImage()
        if err != nil {
            log.Fatal(err)
        }

        if err := os.MkdirAll(dirpath, 0777); err != nil {
            log.Fatal(err)
        }

        file, err := os.Create(dirpath + name + "_" + strconv.Itoa(count) + ".jpg")
        if err != nil {
            log.Fatal(err)
        }
        defer file.Close()

        jpeg.Encode(file, image, &jpeg.Options{ Quality:100, })
    }
    endT1 := time.Now()
    fmt.Printf("making wallpaper done %f[sec]\n", (endT1.Sub(startT1)).Seconds())
}

出力された画像

イベントで撮影してきた写真を素材にして、以下のように出力されました。生成された画像の解像度が大きすぎたので縮小した画像を載せました。
edit-001.jpg

感想

GoCVを利用すれば私のやりたかったことはできました。しかし、やはりPythonやJuliaのほうが書きやすかったですね。ただ、通常の画像処理で利用するならGoCVでいろいろできそうだなーと思いました。

reinsF82
プログラミング、仮想化技術、画像処理、機械学習、ネットワーク、情報セキュリティ等に興味あり。イラスト画像を集めるためにスクレイピングついて勉強中。
http://reinforce82.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした