在go语言中使用OpenCV实现检测颜色的示例
如何用OpenCV和Golang识别颜色名称的代码例子,它可以检测红、绿、蓝三种颜色。我把它作为一个练习,让你来实现黄色的颜色识别。
顺便说一下,这并不是一个真正的好的解决方案(但它能完成工作)....,只是因为它依赖于太多的 "IF "语句。
正确的方法应该是使用一个矩阵,检查一个颜色的十进制代码是否在这个范围内。
然而,在这个阶段,我只需要一个快速的方法来用OpenCV告诉一个颜色的名字。
代码示例:
package main
import (
"fmt"
"image"
"runtime"
"github.com/lazywei/go-opencv/opencv"
"github.com/mattn/go-gtk/glib"
"github.com/mattn/go-gtk/gtk"
)
var (
win = new(opencv.Window)
win2 = new(opencv.Window)
webCamera = new(opencv.Capture)
cascade = new(opencv.HaarCascade)
statusbar = new(gtk.Statusbar)
snapshotFileName string
width, height int
filterOn = true
label *image.RGBA
opencvLabel *opencv.IplImage
whiteColor = opencv.NewScalar(255, 255, 255, 255) // (blue, green, red, alpha)
greenColor = opencv.NewScalar(170, 255, 102, 255) // (blue, green, red, alpha)
blueColor = opencv.NewScalar(255, 0, 0, 255) // (blue, green, red, alpha)
redColor = opencv.NewScalar(0, 0, 255, 255) // (blue, green, red, alpha)
blackColor = opencv.NewScalar(0, 0, 0, 255) // (blue, green, red, alpha)
horizontalScale = float32(0.5)
verticalScale = float32(0.5)
shear = float32(1.0)
thickness = 1
lineType = 8
textFont = opencv.InitFont(opencv.CV_FONT_HERSHEY_SIMPLEX, horizontalScale, verticalScale, shear, thickness, lineType)
)
func detectColor(img *opencv.IplImage) {
//突出我们感兴趣的区域
opencv.Rectangle(img,
opencv.Point{100, 100},
opencv.Point{120, 120},
greenColor, 3, 4, 0)
// 我们要从ROI中提取BGRA值。
//从ROI中提取。取中间的点
scalar := img.Get2D(110, 110)
//fmt.Println(scalar.Val())
scalarArray := scalar.Val()
//fmt.Println(scalarArray)
Bchannel := scalarArray[0]
Gchannel := scalarArray[1]
Rchannel := scalarArray[2]
Achannel := scalarArray[3]
fmt.Println("B,G,R,A : ", Bchannel, Gchannel, Rchannel, Achannel)
// 所以,我们可以得到B,G,R,A的值....time来检测颜色
// 但让我们暂时忽略Alpha通道。
IsBlue(scalarArray, img)
IsGreen(scalarArray, img)
IsRed(scalarArray, img)
win.ShowImage(img)
}
func IsGreen(inputArray [4]float64, img *opencv.IplImage) {
//来自http://www.rapidtables.com/web/color/RGB_Color.htm
//调整上、下限以增加范围和灵敏度
greenUpper := [4]float64{210, 255, 199, 0} // Blue, Green, Red
greenLower := [4]float64{50, 80, 50, 0}
if (inputArray[0] >= greenLower[0]) && (inputArray[0] <= greenUpper[0]) {
if (inputArray[1] >= greenLower[1]) && (inputArray[1] <= greenUpper[1]) {
if (inputArray[2] >= greenLower[2]) && (inputArray[2] <= greenUpper[2]) {
fmt.Println("Green color detected.")
textFont.PutText(img, "I think it is green", opencv.Point{10, 50}, greenColor)
}
}
}
}
func IsRed(inputArray [4]float64, img *opencv.IplImage) {
//来自http://www.rapidtables.com/web/color/RGB_Color.htm
//调整上、下限以增加范围和灵敏度
redUpper := [4]float64{70, 75, 255, 0} // Blue, Green, Red
redLower := [4]float64{15, 15, 100, 0}
if (inputArray[0] >= redLower[0]) && (inputArray[0] <= redUpper[0]) {
if (inputArray[1] >= redLower[1]) && (inputArray[1] <= redUpper[1]) {
if (inputArray[2] >= redLower[2]) && (inputArray[2] <= redUpper[2]) {
fmt.Println("Red color detected.")
textFont.PutText(img, "I think it is red", opencv.Point{10, 50}, redColor)
}
}
}
}
func IsBlue(inputArray [4]float64, img *opencv.IplImage) {
// 我们将只考虑海军蓝、深蓝、中蓝和真蓝。
//来自http://www.rapidtables.com/web/color/RGB_Color.htm
//调整上、下限以增加范围和灵敏度
blueUpper := [4]float64{255, 175, 95, 0}
blueLower := [4]float64{128, 25, 25, 0}
if (inputArray[0] >= blueLower[0]) && (inputArray[0] <= blueUpper[0]) {
if (inputArray[1] >= blueLower[1]) && (inputArray[1] <= blueUpper[1]) {
if (inputArray[2] >= blueLower[2]) && (inputArray[2] <= blueUpper[2]) {
fmt.Println("Blue color detected.")
textFont.PutText(img, "I think it is blue", opencv.Point{10, 50}, blueColor)
}
}
}
}
func processFrameAndUpdate() {
for {
if webCamera.GrabFrame() {
IplImgFrame := webCamera.RetrieveFrame(1)
if IplImgFrame != nil {
// 必须使图像框架
// 小一点,因为性能原因--即速度
// 面积越大,速度就越慢......
IplImgFrame = opencv.Resize(IplImgFrame, 0, height-200, opencv.CV_INTER_LINEAR)
if filterOn == true {
detectColor(IplImgFrame)
} else {
win.ShowImage(IplImgFrame)
}
}
}
}
}
func main() {
cores := runtime.NumCPU()
//最大限度地提高CPU的使用率,以获得最大的性能
runtime.GOMAXPROCS(cores)
fmt.Printf("This machine has %d CPU cores. Using all cores. \n", cores)
//一个新的OpenCV窗口
win = opencv.NewWindow("Go-OpenCV color recognition example")
defer win.Destroy()
//激活网络摄像机
webCamera = opencv.NewCameraCapture(opencv.CV_CAP_ANY) // 自动检测
if webCamera == nil {
panic("Unable to open camera")
}
defer webCamera.Release()
//从相机中获取一些数据
width = int(webCamera.GetProperty(opencv.CV_CAP_PROP_FRAME_WIDTH))
height = int(webCamera.GetProperty(opencv.CV_CAP_PROP_FRAME_HEIGHT))
fmt.Println("Camera width : ", width)
fmt.Println("Camera height : ", height)
//首先打开一个新的 "纯 "OpenCV窗口
go processFrameAndUpdate() //更新摄像机信息的Goroutine
//我们的 "浮动 "GTK工具条
gtk.Init(nil)
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
window.SetPosition(gtk.WIN_POS_CENTER)
window.SetTitle("Go-OpenCV color recognition example")
window.SetIconName("gtk-dialog-info")
window.Connect("destroy", func(ctx *glib.CallbackContext) {
println("got destroy!", ctx.Data().(string))
gtk.MainQuit()
}, "Happy coding!")
vbox := gtk.NewVBox(false, 1)
//--------------------------------------------------------
// GtkVPaned
//--------------------------------------------------------
vpaned := gtk.NewVPaned()
vbox.Add(vpaned)
frame2 := gtk.NewFrame("Go-OpenCV color recognition example")
framebox2 := gtk.NewVBox(false, 1)
frame2.Add(framebox2)
//--------------------------------------------------------
// GtkScale
//--------------------------------------------------------
scaleHBox := gtk.NewHBox(false, 1)
framebox2.PackStart(scaleHBox, false, false, 0)
vpaned.Pack2(frame2, false, false)
//--------------------------------------------------------
// GtkHBox
//--------------------------------------------------------
buttons := gtk.NewHBox(false, 1)
//--------------------------------------------------------
// GtkButton
//--------------------------------------------------------
quitButton := gtk.NewButtonWithLabel("Quit")
quitButton.Clicked(func() {
gtk.MainQuit()
})
buttons.Add(quitButton)
framebox2.PackStart(buttons, false, false, 0)
//--------------------------------------------------------
// GtkVSeparator
//--------------------------------------------------------
vsep := gtk.NewVSeparator()
framebox2.PackStart(vsep, false, false, 0)
statusbar = gtk.NewStatusbar()
context_id := statusbar.GetContextId("go-gtk")
combos := gtk.NewHBox(false, 1)
//--------------------------------------------------------
// GtkStatusbar and GtkComboBox
//--------------------------------------------------------
combobox := gtk.NewComboBoxNewText()
combobox.AppendText("Detect color")
combobox.AppendText("No color detection")
combobox.SetActive(0) // Detect color
combobox.Connect("changed", func() {
println("value:", combobox.GetActiveText())
if combobox.GetActiveText() == "Detect color" {
statusbar.Push(context_id, "Detecting color in region of interest (ROI).")
filterOn = true
} else {
statusbar.Push(context_id, "Not detecting color in region of interest (ROI).")
filterOn = false
}
})
combos.Add(combobox)
framebox2.PackStart(combos, false, false, 0)
//--------------------------------------------------------
// GtkStatusbar
//--------------------------------------------------------
framebox2.PackStart(statusbar, false, false, 0)
//--------------------------------------------------------
// Event
//--------------------------------------------------------
window.Add(vbox)
window.SetSizeRequest(400, 85)
window.ShowAll()
gtk.Main()
}
相关文章