啧啧 都看看 Go 都干了些啥 🏆 技术专题第二期 Go

Go 语言都能做些什么呢

大家好,我是好家伙,漫画 Go 语言小册的作者。这次我要给大家带来一些关于Go语言的一些分享。作为一个程序员,身处这个时代,掌握一门技术,就如同修得一身好武功一样,不仅要经过不断地实战经验,还要有足够的热情,循序渐进才能到达高手的境界。在众多开发语言中,如何才能找到一个适合自己修炼的武功秘籍。那就得对这个语言有所了解。知道它的威力,才能更好的掌握,成为高手就指日可待。

Go 语言作为一门后端语言,到底能够有多大威力,具体能够做些什么,到底能够发出什么样的招式才能够吸引你学习它?那么接下来就简单露几招,还望各位大佬们指教!

gocv 计算机视觉


OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉和机器学习软件库,可以运行在Linux、Windows、Android和Mac OS操作系统上。实现了图像处理和计算机视觉方面的很多通用算法。
OpenCV用C++语言编写,它具有C ++,Python,Java和MATLAB接口,并支持Windows,Linux,Android和Mac OS,OpenCV主要倾向于实时视觉应用, 如今也提供对于C#、Ch、Ruby,GO的支持也就是gocv。https://gocv.io/

  • 安装 gocv go get -u -d gocv.io/x/gocv
  • 安装 MinGW-W64 https://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win32/Personal%20Builds/mingw-builds/7.3.0/
  • 安装CMake https://cmake.org/download/
  • 安装编译gocv
1
2
go复制代码chdir %GOPATH%\src\gocv.io\x\gocv
win_build_opencv.cmd

gocv将图片二值化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
go复制代码package main

import (
"gocv.io/x/gocv"
)

//测试示例
func main() {
filename := "test.png"
window := gocv.NewWindow("Hello")
img := gocv.IMRead(filename, gocv.IMReadColor)
destImage := gocv.NewMat()
//二值化 转为灰度图
gocv.CvtColor(img, &destImage, gocv.ColorBGRToGray)

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

gocv 人脸检测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
go复制代码package main

import (
"fmt"
"image"
"image/color"
"os"

"gocv.io/x/gocv"
)

func main() {
if len(os.Args) < 3 {
fmt.Println("How to run:\n\tfacedetect [camera ID] [classifier XML file]")
return
}

// parse args
deviceID := os.Args[1]
xmlFile := os.Args[2]

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

// open display window
window := gocv.NewWindow("Face Detect")
defer window.Close()

// prepare image matrix
img := gocv.NewMat()
defer img.Close()

// color for the rect when faces detected
blue := color.RGBA{0, 0, 255, 0}

// load classifier to recognize faces
classifier := gocv.NewCascadeClassifier()
defer classifier.Close()

if !classifier.Load(xmlFile) {
fmt.Printf("Error reading cascade file: %v\n", xmlFile)
return
}

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
}

// detect faces
rects := classifier.DetectMultiScale(img)
fmt.Printf("found %d faces\n", len(rects))

// draw a rectangle around each face on the original image,
// along with text identifing as "Human"
for _, r := range rects {
gocv.Rectangle(&img, r, blue, 3)

size := gocv.GetTextSize("Human", gocv.FontHersheyPlain, 1.2, 2)
pt := image.Pt(r.Min.X+(r.Min.X/2)-(size.X/2), r.Min.Y-2)
gocv.PutText(&img, "Human", pt, gocv.FontHersheyPlain, 1.2, blue, 2)
}

// show the image in the window, and wait 1 millisecond
window.IMShow(img)
if window.WaitKey(1) >= 0 {
break
}
}
}

gobot 机器人


gobot 是一个使用Go语言编写的适用于机器人,无人机和物联网的IoT框架。https://gobot.io/

  • 支持35不同平台。
  • 支持输入/输出(GPIO)通讯的设备。
  • 模拟I / O(AIO)驱动程序。
  • I2C驱动程序。
  • SPI驱动器。

树莓派

Raspberry Pi 中文名为树莓派,简写为RPi 只有信用卡大小的微型电脑,其系统基于Linux,它是一款基于ARM的微型电脑主板。可连接键盘、鼠标和网线,具备PC的基本功能。最新版本的树莓派4B,拥有4G内存,引入USB 3.0,支持双屏4K输出,CPU和GPU的速度也更快。

运行在树莓派上的Go程序实现坦克机器人。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
go复制代码package drivers

// import "fmt"

type Motor struct {
PWMA int
AIN1 int
AIN2 int
BIN1 int
BIN2 int
PWMB int
Driver *PCA9685Driver
Debug bool
}

type MotorPosition int

const (
MotorPosition_Left MotorPosition = 0
MotorPosition_Right MotorPosition = 1
MotorPosition_All MotorPosition = -1
)

type MotorDirection int

const (
MotorDirection_Forward MotorDirection = 1
MotorDirection_Backward MotorDirection = -1
)

func NewMotor(driver *PCA9685Driver) *Motor {
motor := &Motor{
PWMA: 0,
AIN1: 1,
AIN2: 2,
BIN1: 3,
BIN2: 4,
PWMB: 5,
Driver: driver,
Debug: false,
}
var PWM float32 = 125
// fmt.Println("设置电机PWM速率:", PWM)
driver.SetPWMFreq(PWM)
return motor
}

// 前进
func (this *Motor) Forward(speed int) {
this.Run(MotorPosition_All, MotorDirection_Forward, speed)
}

//后退
func (this *Motor) Backward(speed int) {
this.Run(MotorPosition_All, MotorDirection_Backward, speed)
}

//左转,原地转向
func (this *Motor) Left(speed int) {
this.Run(MotorPosition_Left, MotorDirection_Backward, speed)
this.Run(MotorPosition_Right, MotorDirection_Forward, speed)
}

//右转,原地转向
func (this *Motor) Right(speed int) {
this.Run(MotorPosition_Right, MotorDirection_Backward, speed)
this.Run(MotorPosition_Left, MotorDirection_Forward, speed)
}

//直接操作电机运转
func (this *Motor) Run(motor MotorPosition, direction MotorDirection, speed int) {
if speed > 100 {
speed = 100
}
//同时操作所有电机
if motor == MotorPosition_All {
this.Run(MotorPosition_Left, direction, speed)
this.Run(MotorPosition_Right, direction, speed)
return
}
//设置默认PWM调速通道为电机a的调速通道
pwmChannel := this.PWMA
//设置默认操作电机为A
PIN1 := this.AIN1
PIN2 := this.AIN2
//根据参数设置操作电机和调速通道为电机B
if motor == MotorPosition_Right {
pwmChannel = this.PWMB
PIN1 = this.BIN1
PIN2 = this.BIN2
}

//如果参数为后退,翻转PIN1和PIN2的位置
if direction == MotorDirection_Backward {
PIN1, PIN2 = PIN2, PIN1
}
// fmt.Println("pwmChannel:", pwmChannel, ",speed:", speed, ",PIN1:", PIN1, ",PIN2:", PIN2)
//设置速度
this.Driver.SetPWM(pwmChannel, 0, uint16(speed*(4096/100)))

//设置正电极
this.Driver.SetPWM(PIN1, 0, 4095)

//设置负电极
this.Driver.SetPWM(PIN2, 0, 0)

}

// func (this *Motor) SetPWM(channel int, on uint16, off uint16) (err error) {
// this.Driver
// if _, err := p.connection.Write([]byte{byte(PCA9685_LED0_ON_L + 4*channel), byte(on), byte(on >> 8), byte(off), byte(off >> 8)}); err != nil {
// return err
// }

// return
// }

func (this *Motor) MotorStop(motor MotorPosition) {
if motor == MotorPosition_All {
this.MotorStop(MotorPosition_Left)
this.MotorStop(MotorPosition_Right)
return
}
//设置默认PWM调速通道为电机a的调速通道
pwmChannel := this.PWMA
if motor == MotorPosition_Right {
pwmChannel = this.PWMB
}
//设置速度
this.Driver.SetPWM(pwmChannel, 0, 0)
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
go复制代码package core

import (
"fmt"
"gobot.io/x/gobot"
"airobot/robot/drivers"
"gobot.io/x/gobot/platforms/raspi"
)

//机器人主结构,存储gobot实例和各个初始化的驱动以及操作器
type Robot struct {
//gobot实例
gobot *gobot.Robot
//主板适配器
adaptor *raspi.Adaptor
//电机操作板驱动
motorDriver *drivers.PCA9685Driver
//电机操作器
motor *drivers.Motor
//电机操作指令列队
motorCmds chan (*CMDData)
}

//初始化机器人监听
func (this *Robot) Start() {
this.motorCmds = make(chan (*CMDData), 100)
go this.listenMotorCmds()
}

func (this *Robot) listenMotorCmds() {
m := NewMotor(this)
wait:
cmd := <-this.motorCmds
m.execute(cmd)
goto wait
}

//机器人状态通道,用于通知webapi启动,启动过程中通道会压入0,启动完成后压入1.
var RobotState = make(chan int, 1)

//机器人操作指令主通道,通过websocket接收指令并压入此通道
var RobotCMD = make(chan *CMD, 100)

//全局机器人实例
var bot *Robot

//机器人启动方法
func StartRobot() {

bot = &Robot{}

fmt.Println("机器人开始启动.")
RobotState <- 0
fmt.Println("初始化主板适配器.")
bot.adaptor = raspi.NewAdaptor()
fmt.Println("初始化电机驱动.")
bot.motorDriver = drivers.NewPCA9685Driver(bot.adaptor)
bot.Start()
work := func() {
fmt.Println("初始化电机操作器.")
bot.motor = drivers.NewMotor(bot.motorDriver)
// var PWM float32 = 125
// fmt.Println("设置电机PWM速率:", PWM)
// bot.motorDriver.SetPWMFreq(PWM)
fmt.Println("机器人启动完成.")
fmt.Println("机器人开始等待指令.")
RobotState <- 1
begin:
cmd := <-RobotCMD
// fmt.Println("接收到指令:", cmd)

switch cmd.Channel {
case "motor":
bot.motorCmds <- &cmd.Data
break
}
goto begin
}

robot := gobot.NewRobot("tankBot",
[]gobot.Connection{bot.adaptor},
[]gobot.Device{bot.motorDriver},
work,
)
robot.Start()
}


视频直播服务

livego 使用纯 go 语言写的一款简单高效的直播服务器。https://github.com/gwuhaolin/livego

  • 支持的传输协议 RTMP, AMF,HLS,HTTP-FLV
  • 支持的容器格式 FLV,TS
  • 支持的编码格式 H264,AAC, MP3

使用

  • 1 启动服务:执行 livego 二进制文件启动 livego 服务;
  • 2 访问 http://localhost:8090/control/get?room=movie 获取一个房间的channelkey(channelkey用于推流,movie用于播放).
  • 3 推流: 通过RTMP协议推送视频流到地址 rtmp://localhost:1935/{appname}/{channelkey} (appname默认是live)

例如: 使用 ffmpeg -re -i demo.flv -c copy -f flv

1
go复制代码rtmp://localhost:1935/{appname}/{channelkey} 推流(下载demo flv);

播放: 支持多种播放协议,播放地址如下:
RTMP:rtmp://localhost:1935/{appname}/movie
FLV:http://127.0.0.1:7001/{appname}/movie.flv
HLS:http://127.0.0.1:7002/{appname}/movie.m3u8

1
2
go复制代码//ffmpeg命令 推流
ffmpeg -re -i demo.flv -c copy -f flv rtmp://localhost:1935/{appname}/{channelkey}

文档地址:https://github.com/gwuhaolin/livego/blob/master/README_cn.md

CRON 定时任务


go语言支持cron定时任务 https://github.com/jakecoffman/cron

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
go复制代码package main

import (
"fmt"

"github.com/jakecoffman/cron"
)

func main() {
c := cron.New()
//每天早上6点执行Testfun函数
c.AddFunc("0 0 6 * * ? ", Testfunc, "定时任务")
c.Start()
}

func Testfunc() {
fmt.Println("定时任务")
//TODO 处理逻辑....
}

Excelize 一个 Go 语言版本的 Excel 文档 API


Go 语言编写的用于操作 Office Excel 文档基础库,基于 ECMA-376,ISO/IEC 29500 国际标准。可以使用它来读取、写入由 Microsoft Excel™ 2007 及以上版本创建的电子表格文档。支持 XLSX / XLSM / XLTM 等多种文档格式,高度兼容带有样式、图片(表)、透视表、切片器等复杂组件的文档,并提供流式读写 API

  • 文档地址:https://xuri.me/excelize/zh-hans/
  • 项目地址:https://github.com/360EntSecGroup-Skylar/excelize
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
go复制代码package main

import (
"fmt"
"github.com/360EntSecGroup-Skylar/excelize"
)

func main() {
f := excelize.NewFile()
// 创建一个 sheet
index := f.NewSheet("Sheet1")
// 设置值
f.SetCellValue("Sheet2", "A2", "Hello world.")
f.SetCellValue("Sheet1", "B2", 100)
// 设置工作簿的活动工作表。
f.SetActiveSheet(index)
// 保存excel
if err := f.SaveAs("Book1.xlsx"); err != nil {
fmt.Println(err)
}
}

🏆 技术专题第二期 | 我与 Go 的那些事……

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%