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
chdir %GOPATH%\src\gocv.io\x\gocv win_build_opencv.cmd
gocv将图片二值化
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 人脸检测
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程序实现坦克机器人。
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)
}
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
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
//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
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
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)
}
}