Golang : Detect face in uploaded photo like GPlus
Problem:
You have an app or website that allow users to upload their profile photo to your server. However, you want to discourage the users from uploading profile photo or avatar that has no real human face. Also you want to impress the users that your website or app is backed a smart artificial intelligence software.
Something like what Google Plus did when a user uploaded a picture without an actual human face. It will tease the user with....
"Are you sure people will recognize you in this photo? It doesn't seem to have a face in it."
How to do that?
Solution:
Combine these two previous tutorials how to upload file in Golang and how to detect faces or vehicles in a photo with OpenCV to produce the backend server program below.
Here you go!
package main
import (
"fmt"
"github.com/lazywei/go-opencv/opencv"
"image"
gif "image/gif"
_ "image/jpeg"
_ "image/png"
"io"
"net/http"
"os"
)
var cascade = new(opencv.HaarCascade)
func uploadHandler(w http.ResponseWriter, r *http.Request) {
// the FormFile function takes in the POST input id file
file, header, err := r.FormFile("file")
if err != nil {
fmt.Fprintln(w, err)
return
}
defer file.Close()
// put the uploaded file in the same directory
// as the server executable
out, err := os.Create(header.Filename)
if err != nil {
fmt.Fprintf(w, "Unable to create the file for writing. Check your write access privilege")
return
}
defer out.Close()
// write the content from POST to the file
_, err = io.Copy(out, file)
if err != nil {
fmt.Fprintln(w, err)
}
// now try to detect face in the file
// we will use Go's method to load the upload file
// instead of openCV.LoadImage
// because we want to detect if the user supplies animated GIF or not
imageFile, err := os.Open(header.Filename)
if err != nil {
fmt.Fprintf(w, "Unable to read uploaded file. ")
return
}
defer imageFile.Close()
img, _, err := image.Decode(imageFile)
if err != nil {
fmt.Fprintf(w, "Unable to decode uploaded file. ")
return
}
buffer := make([]byte, 512)
imageFile.Seek(0, 0) // reset reader
_, err = imageFile.Read(buffer)
if err != nil {
fmt.Fprintf(w, "Unable to read uploaded file. ")
return
}
filetype := http.DetectContentType(buffer)
// check if image is GIF and if yes, check to see if it is animated GIF by
// counting the LoopCount number
if filetype == "image/gif" {
imageFile.Seek(0, 0)
// warn if image is animated GIF
gif, err := gif.DecodeAll(imageFile)
if err != nil {
fmt.Fprintf(w, "Unable to read uploaded .gif file. ")
return
}
if gif.LoopCount != 0 {
fmt.Println("Animated gif detected. Will only scan for faces in the 1st frame.")
}
}
cascade = opencv.LoadHaarClassifierCascade("./haarcascade_frontalface_alt.xml")
defer cascade.Release()
// convert Go's image.Image type to OpenCV's IplImage(Intel Image Processing Library)
openCVimg := opencv.FromImage(img)
defer openCVimg.Release()
if openCVimg != nil {
faces := cascade.DetectObjects(openCVimg)
if len(faces) == 0 {
fmt.Fprintf(w, "Are you sure people will recognize you in this photo? It doesn't seem to have a face in it.\n") // <------- here !
} else {
fmt.Fprintf(w, "Detected [%v] faces in image.\n", len(faces))
fmt.Printf("Detected [%v] faces in image.\n", len(faces))
}
} else {
fmt.Fprintf(w, "OpenCV FromImage error")
}
}
func home(w http.ResponseWriter, r *http.Request) {
html := `<html>
<title>Upload photo and detect face</title>
<body>
<form action="http://localhost:8888/receiveupload" method="post" enctype="multipart/form-data">
<label for="file">Filename:</label>
<input type="file" name="file" id="file"><br>
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>`
w.Write([]byte(fmt.Sprintf(html)))
}
func main() {
http.HandleFunc("/receiveupload", uploadHandler)
http.HandleFunc("/", home)
http.ListenAndServe(":8888", nil)
}
- Build the program and run it.
- Point your browser to localhost:8888 and you will be prompted with a page to upload an image file.
- Play around with photos that have a human face and those that don't. You will see different output.
Happy coding!
References:
https://www.socketloop.com/tutorials/golang-upload-file
https://www.socketloop.com/tutorials/golang-detect-number-of-faces-or-vehicles-in-a-photo
See also : Golang : Detect number of faces or vehicles in a photo
By Adam Ng
IF you gain some knowledge or the information here solved your programming problem. Please consider donating to the less fortunate or some charities that you like. Apart from donation, planting trees, volunteering or reducing your carbon footprint will be great too.
Advertisement
Tutorials
+9.3k Golang : Eroding and dilating image with OpenCV example
+7.3k Golang : Error reading timestamp with GORM or SQL driver
+6.6k Golang : Levenshtein distance example
+22.3k Golang : Strings to lowercase and uppercase example
+11.8k Golang : convert(cast) string to integer value
+40.5k Golang : How to check if a string contains another sub-string?
+8.2k Linux/Unix : fatal: the Postfix mail system is already running
+18.6k Golang : Calculate entire request body length during run time
+8.6k Golang : io.Reader causing panic: runtime error: invalid memory address or nil pointer dereference
+5.1k How to check with curl if my website or the asset is gzipped ?
+6.2k Golang : Embedded or data bundling example
+9.5k Golang : Get current, epoch time and display by year, month and day