パーソナルブログメモリ

a = [1, 1]
for _ in "*" * 999: a += [sum(a[-2:])]
print(a)

golang 3日目 画像処理

2017-03-19 | コンピュータ
go言語の画像処理に相当苦労しました。未だにバグは取れていないのですが

今回でgoはいったん終了します。



<個人的な感想>

時期尚早、様子見。主流になる望みは微妙。キャラが...


以下は次回挑戦するときへのメモ書きです。

<はまった点>

・ 画像のピクセルデータを取得する関数。sdl-imageを探したのですがいいものが見つからず。imageを使いました。pixelではなくてAtというのもはまった。
・ import文 _ "image/png"のアンダーバー普通にするとコンパイルが通らないし外すと画像読み込み時にエラーになる。pngを使っていることをコンパイル段階ではわからないのでアンダーバーをつける謎技術。
・ 変数の定義方法。相当こだわりがあるのでしょうが他の言語と違うのでちょいちょいエラー。
・ colorの各色の定義方法がSDLだとuint8でcolorだとuint32。uint8(n)でキャストしていますが正しいのか不明。
・ 配列の定義の方法。他のサイトだと数個のものしか見つからず。2次元もよくわからないので結局1次元で配列の枠分appendという力技対応。
・ math算術パッケージがfloat64。単につかったことのない型なので。
・ :=で後の形式をそのまま変数定義に使える点。どこで定義しているのかしばらく謎技術でした。関数のライブラリを見ないといけない。
・ まだ新しい言語なのか解説サイトのサンプルがほとんどない。あればピンポイント情報が得られやすいのですが延々ライブラリとにらめっこしました。とちゅう疲れ果ててバカのように笑っていたかも。
・ なぜかアプリがしばらくすると灰色になる。メモリ解放かなにか失敗しているのか解決してません。調べる気力は現時点でありません。
・ 定義した変数を使っていないとコンパイルが通らない。ワーニングで通しているものとばっかり思ったので何故変わらんと最初は思考がループしていました。



<速度計測>

Python 2.5
go 0.5
Processing 0.25
(秒/フレーム)

Python3.5.2-pygame
go1.6.2-SDL2
java1.8.0(processing版?)-Processing3.3



<参考サイト>

goDoc
The Go Programming Language



<利用画像>

world.png


hi.png プログラムに合わせて一部加工しています。

画像引用元 国土地理院 地球地図全球版
画像のCopyright. Geospatial Information Authority of Japan. ALL RIGHTS RESERVED.



<画像スナップ>

タイトル さらばアメリカ (バグが取れていない偶然の作品です)




<ubuntuでの動かし方>

ざっくり
goをインストール
gitをインストール、登録、ssh-keyの設定(隠しフォルダで苦戦。必須か不明)

gopathの設定 export GOPATH="$HOME/go"
(設定の保存をしていないので都度実行)
sdl2の取得  go get -v github.com/veandco/go-sdl2/sdl{,_mixer,_image,_ttf}
(exampleにソースがいろいろあります。コンパイルでimportがxxxがないと言われたら、ひたすらgo get xxx)
コンパイル go build world.go
画像ファイルがコンパイルファイルと同じフォルダに必要です。



<プログラムリスト>

world.go
package main

import (
    "fmt"
    "math"
    "math/rand"
    "time"
    "github.com/veandco/go-sdl2/sdl"
    "os"
    "image"
    "image/color"

    _ "image/png"
)

var winTitle string = "world"
var winWidth, winHeight int = 1400,700
var imageName string = "./world.png"
var imageName2 string = "./hi.png"

var window *sdl.Window
var renderer *sdl.Renderer
var err error
var col2 color.Color
var r,g,b uint32
    
var ar [] uint8
var ag [] uint8
var ab [] uint8
var hr [] uint8
var hg [] uint8
var hb [] uint8
var hland[] int
var p,s,bs,bh int
    
var px float64
var py float64
var sc float64
var wx int
var wy int
var t = 0.0
    
func run() int {

    px = 180
    py = 120
    sc = 1000.0
    wx = 373
    wy = 186
    
    hi := [...]int{-20,-20,-20,-20,-20,-20,-20,-20,-20,-10,0,20,40,60,80,100,125,150,175,200,225,250,275,300,350,400,450,500,600,700,800,900,1000,1500,2000,3000,4000,5000,6000,7000}

    rand.Seed(time.Now().UnixNano())

    file1, err := os.Open("world.png")
    defer file1.Close()
    if err != nil {
         fmt.Println(err)
         return 7
    }
    img1, _, err := image.Decode(file1)
    if err != nil {
        fmt.Println(err)
        return 8
    }
    for y := 0; y < 186; y++ {
        for x := 0; x < 373; x++ {
            hland = append(hland,0)     
            ar = append(ar, 0)
            ag = append(ag, 0)
            ab = append(ab, 0)      }
    }   
    for y := 0; y < 186; y++ {
        for x := 0; x < 373; x++ {
            p=y*373+x
            col2 = img1.At(x,y)
            r,g,b,_ = col2.RGBA()           
            ar[p] = uint8(r)
            ag[p] = uint8(g)
            ab[p] = uint8(b)
        }
    }
    
    file2, err := os.Open("hi.png")
    defer file2.Close()
    if err != nil {
        fmt.Println(err)
        return 9
    }
    img2, _, err := image.Decode(file2)
    if err != nil {
        fmt.Println(err)
        return 10
    }
    for i := 0; i < 40; i++ {
        hr = append(hr, 0)
        hg = append(hg, 0)
        hb = append(hb, 0)
    }
    for i := 0; i < 40; i++ {
        col2 = img2.At((i+2)*10,40)
        r,g,b,_ = col2.RGBA()           
        hr[i] = uint8(r)
        hg[i] = uint8(g)
        hb[i] = uint8(b)
    }

    for y := 0; y < 186; y++ {
        for x := 0; x < 373; x++ {
            bs=10000
            bh=1000
            p=y*373+x
            for j:=0;j<40;j++{
                s=int(math.Abs(float64(hr[j]-ar[p]))+math.Abs(float64(hg[j]-ag[p]))+math.Abs(float64(hb[j]-ab[p])))
                if s<bs{
                    bs=s
                    bh=hi[j]+40
                }
            }
            hland[p] = bh       
        }
    }

    window, err = sdl.CreateWindow(winTitle, sdl.WINDOWPOS_UNDEFINED, sdl.WINDOWPOS_UNDEFINED,
        winWidth, winHeight, sdl.WINDOW_SHOWN)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to create window: %s\n", err)
        return 1
    }
    defer window.Destroy()

    renderer, err = sdl.CreateRenderer(window, -1, sdl.RENDERER_ACCELERATED)
    if err != nil {
        fmt.Fprintf(os.Stderr, "Failed to create renderer: %s\n", err)
        return 2
    }
    defer renderer.Destroy()

    for i := 0; i < 20; i++ {
        start := time.Now();
        renderer.Clear()

        renderer.SetDrawColor(50,255,255, 255)
        renderer.FillRect(&sdl.Rect{0, 0, int32(winWidth), int32(winHeight)})

        theworld(renderer)

        renderer.Present()

        px=px+1
        t=t+0.1

        end := time.Now();
        fmt.Printf("%f秒\n",(end.Sub(start)).Seconds())
    }

    return 0
}
func theworld(renderer *sdl.Renderer){

    el := 1400.0
    eh:= 30000.0
    ez:= 0.0
    ex:= 0.0
    hwix:= 700
    hwiy:= 200
    mx:= 0
    my:= 0
    tx:=0.0
    ty:=0.0
    cot:=math.Cos(t)
    sit:=math.Sin(t)
    var h int
    for y := 3; y < 500; y++ {
        ez=el*eh/float64(y)
        for x := 0; x < 1400; x++ {
            ex=float64(x-hwix)*ez/el
            tx=(ex*cot-ez*sit)/sc
            ty=(ex*sit+ez*cot)/sc
            mx=int(px+tx)
            my=int(py-ty)
            if (mx<0)||(my<0)||(mx>=wx)||(my>=wy){
                continue            
            }   
            p=my*373+mx     
            renderer.SetDrawColor(ar[p],ag[p],ab[p],255)
            h=int( hland[p]*5/int (math.Sqrt( tx*tx+ty*ty) ) )
            renderer.DrawLine(x, y+hwiy, x, y+hwiy+h)
        }
    }       
}


func main() {
    os.Exit(run())
}

最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。