mirror of
https://github.com/esimov/pigo.git
synced 2025-10-28 10:11:27 +08:00
Continue working on face triangulator example
This commit is contained in:
@@ -64,6 +64,7 @@ while(True):
|
|||||||
dets = process_frame(pixs) # pixs needs to be np.uint8 array
|
dets = process_frame(pixs) # pixs needs to be np.uint8 array
|
||||||
if dets is not None:
|
if dets is not None:
|
||||||
for det in dets:
|
for det in dets:
|
||||||
|
#cv2.floodFill
|
||||||
mask = np.zeros((height, width, 3), dtype=np.uint8)
|
mask = np.zeros((height, width, 3), dtype=np.uint8)
|
||||||
mask = cv2.circle(mask, (int(det[1]), int(det[0])), int(det[2]/2.0), np.array([255, 255, 255]), -1)
|
mask = cv2.circle(mask, (int(det[1]), int(det[0])), int(det[2]/2.0), np.array([255, 255, 255]), -1)
|
||||||
frame = np.where(mask!=np.array([255, 255, 255]), frame, cv2.blur(frame, (30, 30), 0))
|
frame = np.where(mask!=np.array([255, 255, 255]), frame, cv2.blur(frame, (30, 30), 0))
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package main
|
|||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -12,6 +11,7 @@ import (
|
|||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/esimov/pigo/core"
|
"github.com/esimov/pigo/core"
|
||||||
|
"github.com/esimov/triangle"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@@ -37,38 +37,81 @@ func FindFaces(pixels []uint8) uintptr {
|
|||||||
rows: 480,
|
rows: 480,
|
||||||
cols: 640,
|
cols: 640,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
proc := &triangle.Processor{
|
||||||
|
BlurRadius: 4,
|
||||||
|
SobelThreshold: 10,
|
||||||
|
PointsThreshold: 20,
|
||||||
|
MaxPoints: 100,
|
||||||
|
Wireframe: 0,
|
||||||
|
Noise: 0,
|
||||||
|
StrokeWidth: 1,
|
||||||
|
IsSolid: false,
|
||||||
|
Grayscale: false,
|
||||||
|
OutputToSVG: false,
|
||||||
|
OutputInWeb: false,
|
||||||
|
}
|
||||||
|
tri := &triangle.Image{*proc}
|
||||||
|
|
||||||
pointCh := make(chan uintptr)
|
pointCh := make(chan uintptr)
|
||||||
|
|
||||||
dets := px.clusterDetection(pixels)
|
dets := px.clusterDetection(pixels)
|
||||||
img := px.convertPixToImage(pixels)
|
img := px.pixToImage(pixels)
|
||||||
|
|
||||||
|
tFaces := make([][]int, len(dets))
|
||||||
result := make([][]int, len(dets))
|
result := make([][]int, len(dets))
|
||||||
|
det := make([]int, 0, len(dets))
|
||||||
|
|
||||||
for i := 0; i < len(dets); i++ {
|
totalPixDim := 0
|
||||||
if dets[i].Q >= 5.0 {
|
|
||||||
result[i] = append(result[i], dets[i].Row, dets[i].Col, dets[i].Scale)
|
|
||||||
rect := image.Rect(
|
|
||||||
dets[i].Col-dets[i].Scale/2,
|
|
||||||
dets[i].Row-dets[i].Scale/2,
|
|
||||||
dets[i].Scale,
|
|
||||||
dets[i].Scale,
|
|
||||||
)
|
|
||||||
subImg := img.(SubImager).SubImage(rect)
|
|
||||||
fmt.Println(subImg.Bounds())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
det := make([]int, 0, len(result))
|
|
||||||
go func() {
|
go func() {
|
||||||
|
for i := 0; i < len(dets); i++ {
|
||||||
|
if dets[i].Q >= 5.0 {
|
||||||
|
result[i] = append(result[i], dets[i].Row, dets[i].Col, dets[i].Scale)
|
||||||
|
rect := image.Rect(
|
||||||
|
dets[i].Col-dets[i].Scale/2,
|
||||||
|
dets[i].Row-dets[i].Scale/2,
|
||||||
|
dets[i].Scale,
|
||||||
|
dets[i].Scale,
|
||||||
|
)
|
||||||
|
|
||||||
|
subImg := img.(SubImager).SubImage(rect)
|
||||||
|
bounds := subImg.Bounds()
|
||||||
|
|
||||||
|
if bounds.Dx() > 1 && bounds.Dy() > 1 {
|
||||||
|
triRes, _, _, err := tri.Draw(subImg, false, func() {})
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err.Error())
|
||||||
|
}
|
||||||
|
triPix := px.imgToPix(triRes)
|
||||||
|
tFaces[i] = append(tFaces[i], triPix...)
|
||||||
|
|
||||||
|
// Prepend the top left coordinates of the detected faces to the delaunay triangles.
|
||||||
|
tFaces[i] = append([]int{len(triPix), bounds.Min.X, bounds.Min.Y}, tFaces[i]...)
|
||||||
|
totalPixDim += len(triPix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Since in Go we cannot transfer a 2d array trough an array pointer
|
// Since in Go we cannot transfer a 2d array trough an array pointer
|
||||||
// we have to transform it into 1d array.
|
// we have to transform it into 1d array.
|
||||||
for _, v := range result {
|
for _, v := range result {
|
||||||
det = append(det, v...)
|
det = append(det, v...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert the multidimmensional slice containing the triangulated images to 1d slice.
|
||||||
|
convTri := make([]int, 0, len(result)+totalPixDim)
|
||||||
|
for _, v := range tFaces {
|
||||||
|
convTri = append(convTri, v...)
|
||||||
|
}
|
||||||
|
|
||||||
// Include as a first slice element the number of detected faces.
|
// Include as a first slice element the number of detected faces.
|
||||||
// We need to transfer this value in order to define the Python array buffer length.
|
// We need to transfer this value in order to define the Python array buffer length.
|
||||||
det = append([]int{len(result), 0, 0}, det...)
|
det = append([]int{len(result), 0, 0}, det...)
|
||||||
|
|
||||||
|
// Append the generated triangle slices to detected faces array.
|
||||||
|
det = append(det, convTri...)
|
||||||
|
|
||||||
// Convert the slice into an array pointer.
|
// Convert the slice into an array pointer.
|
||||||
s := *(*[]int)(unsafe.Pointer(&det))
|
s := *(*[]int)(unsafe.Pointer(&det))
|
||||||
p := uintptr(unsafe.Pointer(&s[0]))
|
p := uintptr(unsafe.Pointer(&s[0]))
|
||||||
@@ -122,7 +165,8 @@ func (px pixs) clusterDetection(pixels []uint8) []pigo.Detection {
|
|||||||
return dets
|
return dets
|
||||||
}
|
}
|
||||||
|
|
||||||
func (px pixs) convertPixToImage(pixels []uint8) image.Image {
|
// pixToImage converts the pixel array to an image.
|
||||||
|
func (px pixs) pixToImage(pixels []uint8) image.Image {
|
||||||
width, height := px.cols, px.rows
|
width, height := px.cols, px.rows
|
||||||
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
img := image.NewRGBA(image.Rect(0, 0, width, height))
|
||||||
c := color.RGBA{
|
c := color.RGBA{
|
||||||
@@ -143,3 +187,19 @@ func (px pixs) convertPixToImage(pixels []uint8) image.Image {
|
|||||||
}
|
}
|
||||||
return img
|
return img
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// imgToPix converts the image to a pixel array.
|
||||||
|
func (px pixs) imgToPix(img image.Image) []int {
|
||||||
|
bounds := img.Bounds()
|
||||||
|
x := bounds.Dx()
|
||||||
|
y := bounds.Dy()
|
||||||
|
pixels := make([]int, 0, x*y*3)
|
||||||
|
|
||||||
|
for i := bounds.Min.X; i < bounds.Max.X; i++ {
|
||||||
|
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
|
||||||
|
r, g, b, _ := img.At(i, j).RGBA()
|
||||||
|
pixels = append(pixels, int(r>>8), int(g>>8), int(b>>8), 255)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return pixels
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user