GoCv DNN 风格迁移

参考 gocv

下载模型

// downlaod.sh
BASE_URL="http://cs.stanford.edu/people/jcjohns/fast-neural-style/models/"

mkdir -p models/instance_norm
cd models/instance_norm
curl -O "$BASE_URL/instance_norm/candy.t7"
curl -O "$BASE_URL/instance_norm/la_muse.t7"
curl -O "$BASE_URL/instance_norm/mosaic.t7"
curl -O "$BASE_URL/instance_norm/feathers.t7"
curl -O "$BASE_URL/instance_norm/the_scream.t7"
curl -O "$BASE_URL/instance_norm/udnie.t7"

mkdir -p ../eccv16
cd ../eccv16
curl -O "$BASE_URL/eccv16/the_wave.t7"
curl -O "$BASE_URL/eccv16/starry_night.t7"
curl -O "$BASE_URL/eccv16/la_muse.t7"
curl -O "$BASE_URL/eccv16/composition_vii.t7"
cd ../../

共十个模型:

main.go

package main

import (
	"fmt"
	"image"
	"os"

	"gocv.io/x/gocv"
)

func main() {

	// 判断执行指令时的参数个数,参数 0 为运行的主文件,参数 1 为输入源,参数 2 为模型 ,参数 3 为端点,参数 4 为设备
	if len(os.Args) < 3 {
		fmt.Println("How to run:\ndnn-style-transfer [videosource] [modelfile] ([backend] [device])")
		return
	}

	// 参数转换
	deviceID := os.Args[1]
	model := os.Args[2]
	backend := gocv.NetBackendDefault
	if len(os.Args) > 3 {
		backend = gocv.ParseNetBackend(os.Args[3])
	}

	target := gocv.NetTargetCPU
	if len(os.Args) > 4 {
		target = gocv.ParseNetTarget(os.Args[4])
	}

	window := gocv.NewWindow("DNN Style Transfer")
	defer window.Close()

	// 读取的图片位置
	img := gocv.IMRead(deviceID, gocv.IMReadColor)
	defer img.Close()

	// 打开下载好的 DNN 风格迁移模型
	net := gocv.ReadNet(model, "")
	if net.Empty() {
		fmt.Printf("Error reading network model from : %v\n", model)
		return
	}
	defer net.Close()
	net.SetPreferableBackend(gocv.NetBackendType(backend))
	net.SetPreferableTarget(gocv.NetTargetType(target))

	fmt.Printf("Start reading device: %v\n", deviceID)

	// 将 image Mat 转换为 DNN 风格迁移模型可以分析的 640x480 Blob
	blob := gocv.BlobFromImage(img, 1.0, image.Pt(640, 480), gocv.NewScalar(103.939, 116.779, 123.68, 0), false, false)

	// 把转换成的 Blob 放进转换器
	net.SetInput(blob, "")

	// 通过网络运行一个向前传递
	probMat := net.Forward("")
	sz := probMat.Size()
	dims := sz[2] * sz[3]
	out := gocv.NewMatWithSize(480, 640, gocv.MatTypeCV8UC3)

	// 取 blob 并从中获取可显示的 image Mat 图像
	for i := 0; i < dims; i++ {
		r := probMat.GetFloatAt(0, i)
		r += 103.939

		g := probMat.GetFloatAt(0, i+dims)
		g += 116.779

		b := probMat.GetFloatAt(0, i+dims*2)
		b += 123.68

		out.SetUCharAt(0, i*3, uint8(r))
		out.SetUCharAt(0, i*3+1, uint8(g))
		out.SetUCharAt(0, i*3+2, uint8(b))
	}
	// 重置窗口大小,这里适应我的电脑屏幕
	window.ResizeWindow(1366, 768)
	window.IMShow(out)
	// 窗口时间
	window.WaitKey(1000 * 3)
	probMat.Close()
	blob.Close()
	out.Close()

}

目录结构

 运行效果:

// 运行指令, ** 为实际运行的 DNN 模型
go run ./cmd/main.go ./images/003.jpg ./models/**/**.t7 opencv

原图:

效果图: 

composition_vii.t7

la_muse.t7

starry_night.t7

the_wave.t7

candy.t7

feathers.t7

instance_norm/la_muse.t7

mosaic.t7

the_scream.t7 

udnie.t7

实时转换 

通过流来实现实时转换:

// 源代码
// https://github.com/hybridgroup/gocv/blob/release/cmd/dnn-style-transfer/main.go
// What it does:
//
// This example performs real-time style transfer using a deep neural network.
//
// For more information about the model used by this example, go to:
// https://github.com/jcjohnson/fast-neural-style
//
// Download the model file from:
// http://cs.stanford.edu/people/jcjohns/fast-neural-style/models/eccv16/starry_night.t7
//
// How to run:
//
// 		go run ./cmd/dnn-style-transfer/main.go 0 ~/Downloads/starry_night.t7 openvino fp16
//

package main

import (
	"fmt"
	"image"
	"os"

	"gocv.io/x/gocv"
)

func main() {
	// 判断执行指令时的参数个数,参数 0 为运行的主文件,参数 1 为输入源,参数 2 为模型 ,参数 3 为端点,参数 4 为设备
	if len(os.Args) < 3 {
		fmt.Println("How to run:\ndnn-style-transfer [videosource] [modelfile] ([backend] [device])")
		return
	}

	// 参数转换
	deviceID := os.Args[1]
	model := os.Args[2]
	backend := gocv.NetBackendDefault
	if len(os.Args) > 3 {
		backend = gocv.ParseNetBackend(os.Args[3])
	}

	target := gocv.NetTargetCPU
	if len(os.Args) > 4 {
		target = gocv.ParseNetTarget(os.Args[4])
	}

	// open capture device
	webcam, err := gocv.OpenVideoCapture(deviceID)
	if err != nil {
		fmt.Printf("Error opening video capture device: %v\n", deviceID)
		return
	}
	defer webcam.Close()

	window := gocv.NewWindow("DNN Style Transfer")
	defer window.Close()

	img := gocv.NewMat()
	defer img.Close()

	// open DNN style transfer model
	net := gocv.ReadNet(model, "")
	if net.Empty() {
		fmt.Printf("Error reading network model from : %v\n", model)
		return
	}
	defer net.Close()
	net.SetPreferableBackend(gocv.NetBackendType(backend))
	net.SetPreferableTarget(gocv.NetTargetType(target))

	fmt.Printf("Start reading device: %v\n", deviceID)

	for {
		if ok := webcam.Read(&img); !ok {
			fmt.Printf("Device closed: %v\n", deviceID)
			return
		}
		if img.Empty() {
			continue
		}

		// convert image Mat to 640x480 blob that the style transfer can analyze
		blob := gocv.BlobFromImage(img, 1.0, image.Pt(640, 480), gocv.NewScalar(103.939, 116.779, 123.68, 0), false, false)

		// feed the blob into the detector
		net.SetInput(blob, "")

		// run a forward pass thru the network
		probMat := net.Forward("")
		sz := probMat.Size()
		dims := sz[2] * sz[3]
		out := gocv.NewMatWithSize(480, 640, gocv.MatTypeCV8UC3)

		// take blob and obtain displayable Mat image from it
		for i := 0; i < dims; i++ {
			r := probMat.GetFloatAt(0, i)
			r += 103.939

			g := probMat.GetFloatAt(0, i+dims)
			g += 116.779

			b := probMat.GetFloatAt(0, i+dims*2)
			b += 123.68

			out.SetUCharAt(0, i*3, uint8(r))
			out.SetUCharAt(0, i*3+1, uint8(g))
			out.SetUCharAt(0, i*3+2, uint8(b))
		}

		window.IMShow(out)
		if window.WaitKey(1) >= 0 {
			break
		}

		probMat.Close()
		blob.Close()
		out.Close()
	}
}

效果:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余衫马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值