有一首叫《傳奇》的歌裡面唱到:只因為在人群中看了你一眼,從此沒能忘掉你容顏。這就有一個問題了,如何在一張合照中匹配出特定的那個人?
前面有篇文章講解了如何安裝golang的opencv庫-gocv,我們將使用gocv來解決這個問題。
首先我們先下載一個照片,它長這樣。
侵刪
我們要做的呢,就是把劉亦菲找出來,於是模板長這樣
話不多說,程式碼開搞。
package mainimport ( "fmt" "os" "gocv.io/x/gocv" "log" "image/color" "image")
首先從命令列獲取 模板圖片和要搜尋的圖片
template:=os.Args[1] src:=os.Args[2] imgTempl:=gocv.IMRead(template,gocv.IMReadGrayScale)//轉化為灰度,好計算 if imgTempl.Empty(){ log.Printf("Invalid read of %s",template) return //為空,返回 } defer imgTempl.Close() imgSrc:=gocv.IMRead(src,gocv.IMReadGrayScale) //轉化為灰度,好計算 if imgSrc.Empty(){ log.Printf("Invalid read of %s",src) return //為空,返回 } defer imgSrc.Close() imgSrc1:=gocv.IMRead(src,gocv.IMReadColor)//讀取彩色圖,用於展現 if imgSrc1.Empty(){ log.Printf("Invalid read of %s",src) return //為空,返回 } defer imgSrc1.Close()
建立一個視窗,用於展現圖片
window := gocv.NewWindow("Image Match") defer window.Close()
接下來看看主角 MatchTemplate這個函式的用法和作用。
我們開啟控制檯 輸入
go doc gocv.MatchTemplate
得到
MatchTemplate
大意就是在目標影象上面匹配模板。
第一個引數為 mat物件mat,即目標影象,第二個引數為模板影象 也是mat物件,第三個為結果矩陣 mat物件result的指標,第四個為模板匹配方法標誌,可選引數如下:
可選引數
第五個引數為匹配模板的掩碼,和模板影象一樣也是mat物件。
MatchTemplate函式還有一個小夥伴叫做 MinMaxLoc
MinMaxLoc
它的作用就是在一個數組中找到全域性最小值和全域性最大值,透過它,我們可以在結果矩陣中得到最優點即最有可能的區域和最沒可能的區域。它返回最小值,最大值,最小值對應的點,最大值對應的點。
言歸正傳,下面看看怎麼使用。
result:=gocv.NewMat() //用於存放結果矩陣 defer result.Close() m :=gocv.NewMat() //掩碼舉證mask blue := color.RGBA{0, 0, 255, 0} //定義框線的顏色 gocv.MatchTemplate(imgTempl,imgSrc,&result,gocv.TmCcoeffNormed,m) //匹配 m.Close() _,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result) //獲取最大點 if maxConfidence < 0.9 { //0.9為閾值,可適量調整 log.Printf("Max confidence of %f is too low. MatchTemplate could not find template in scene.", maxConfidence) return }
如果沒有滿足條件的點(可能性低於閾值0.9),到這程式就結束了.
如果滿足的話,我們需要將圖片展現,並且將匹配的目標框出來。
rect:=image.Rect(maxLoc.X,maxLoc.Y,maxLoc.X+imgTempl.Cols(),maxLoc.Y+imgTempl.Rows()) gocv.Rectangle(&imgSrc1, rect, blue, 3) for { //設定loop,否則閃現一下就沒了 window.IMShow(imgSrc1) if window.WaitKey('q') >= 0 { //監控鍵盤是否按下Q,是則退出。 break } }
執行程式碼:
go run main.go temp.jpg src.jpg //temp.jpg 為模板頭像,src.jpg為要搜尋的影象
得到結果:
找到啦
最後附上完整程式碼:
// main.go package mainimport ( "fmt" "os" "gocv.io/x/gocv" "log" "image/color" "image")func main() { if len(os.Args) < 3 { fmt.Println("How to run:\n\tMatchImage [Template] [src image]") return } template:=os.Args[1] //模板圖片 src:=os.Args[2] //匹配圖片 imgTempl:=gocv.IMRead(template,gocv.IMReadGrayScale) if imgTempl.Empty(){ log.Printf("Invalid read of %s",template) return //為空,返回 } defer imgTempl.Close() imgSrc:=gocv.IMRead(src,gocv.IMReadGrayScale) if imgSrc.Empty(){ log.Printf("Invalid read of %s",src) return //為空,返回 } defer imgSrc.Close() imgSrc1:=gocv.IMRead(src,gocv.IMReadColor) if imgSrc1.Empty(){ log.Printf("Invalid read of %s",src) return //為空,返回 } defer imgSrc1.Close() window := gocv.NewWindow("Image Match") defer window.Close() result:=gocv.NewMat() defer result.Close() m :=gocv.NewMat() blue := color.RGBA{0, 0, 255, 0} gocv.MatchTemplate(imgTempl,imgSrc,&result,gocv.TmCcoeffNormed,m) m.Close() _,maxConfidence,_,maxLoc :=gocv.MinMaxLoc(result) if maxConfidence < 0.9 { log.Printf("Max confidence of %f is too low. MatchTemplate could not find template in scene.", maxConfidence) return } rect:=image.Rect(maxLoc.X,maxLoc.Y,maxLoc.X+imgTempl.Cols(),maxLoc.Y+imgTempl.Rows()) gocv.Rectangle(&imgSrc1, rect, blue, 3) for { window.IMShow(imgSrc1) if window.WaitKey('q') >= 0 { break } } }
最新評論