— @Malakhor9000
, , «» , Slack- .
«» — , Smite. , , . @Chrisbot. ., , , :
- .
- Slack.
- .
image image/draw Go, , . №1.
, Slack- Go , Google. Go Slack , , , , Slack. №2.
, — .
golang face detect — StackOverflow
go-opencv.
, . №3.
. , , «» .
go-opencv. , opencv Go, Image Rectangle, , .
, opencv.FromImage, image.Image opencv . , opencv.LoadImage, , . Slack.
, XML- Haar , , . facefinder, :
package facefinder
import (
"image"
"github.com/lazywei/go-opencv/opencv"
)
var faceCascade *opencv.HaarCascade
type Finder struct {
cascade *opencv.HaarCascade
}
func NewFinder(xml string) *Finder {
return &Finder{
cascade: opencv.LoadHaarClassifierCascade(xml),
}
}
func (f *Finder) Detect(i image.Image) []image.Rectangle {
var output []image.Rectangle
faces := f.cascade.DetectObjects(opencv.FromImage(i))
for _, face := range faces {
output = append(output, image.Rectangle{
image.Point{face.X(), face.Y()},
image.Point{face.X() + face.Width(), face.Y() + face.Height()},
})
}
return output
}
, :
imageReader, _ := os.Open(imageFile)
baseImage, _, _ := image.Decode(imageReader)
finder := facefinder.NewFinder(haarCascadeFilepath)
faces := finder.Detect(baseImage)
for _, face := range faces {
}
! , . , _ bin.
func loadImage(file string) image.Image {
reader, err := os.Open(file)
if err != nil {
log.Fatalf("error loading %s: %s", file, err)
}
img, _, err := image.Decode(reader)
if err != nil {
log.Fatalf("error loading %s: %s", file, err)
}
return img
}
- :
baseImage := loadImage(imageFile)
chrisFace := loadImage(chrisFaceFile)
bounds := baseImage.Bounds()
finder := facefinder.NewFinder(haarCascadeFilepath)
faces := finder.Detect(baseImage)
canvas := image.NewRGBA(bounds)
draw.Draw(canvas, bounds, baseImage, bounds.Min, draw.Src)
for _, face := range faces {
draw.Draw(
canvas,
face,
chrisFace,
bounds.Min,
draw.Src,
)
}
, , !

, . ! . PNG , . draw.Over draw.Draw. draw.Src !

, , ,
, — , .
, . , - . , , «», - . , image.Rectangle , «» 30%.
, « » , «» . ,
disintegration/imaging, imaging.Fit , , , . , , .
:
for _, face := range faces {
rect := rectMargin(30.0, face)
newFace := chrisFaces.Random()
chrisFace := imaging.Fit(newFace, rect.Dx(), rect.Dy(), imaging.Lanczos)
draw.Draw(
canvas,
rect,
chrisFace,
bounds.Min,
draw.Over,
)
}
, , … !

: - .
Slack
, Slack-. , , Slack-. « » Slack-, .
Google.
,
, , . Slack API, , . :

Slack, Slack . , , Slack . Slack , , , .
. , , , . ! - :
if len(faces) == 0 {
face := imaging.Resize(
chrisFaces[0],
bounds.Dx()/3,
0,
imaging.Lanczos,
)
face_bounds := face.Bounds()
draw.Draw(
canvas,
bounds,
face,
bounds.Min.Add(image.Pt(
-bounds.Max/2+face_bounds.Max.X/2,
-bounds.Max.Y+int(float64(face_bounds.Max.Y)/1.9),
)),
draw.Over,
)
}
:

- , .
, , ? , , .
@Chrisbot

— , ! , , .
— Chrisbot @jhutchinson.
«» .

— ?
—
— , - , .
, , .
, .

@Chrisbot’.







, , . — , go-opencv, , .
, «» Slack’e, , , - «».

— , , . !
: .
https://github.com/zikes/chrisifyhttps://github.com/zikes/mybot