6

Profile Photos, Privacy, and Social Media

 2 years ago
source link: https://medium.com/@rocketlaunchr.cloud/profile-photos-privacy-and-social-media-e66a908cd054
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Profile Photos, Privacy, and Social Media

In the ‘good old days’ of the internet, it was normal (or even quasi-encouraged) to be anonymous. Early adopters wrote blogs and had Hotmail and Messenger accounts using pseudonyms. You couldn’t know someone’s online identity with absolute precision. Nowadays, if you don’t have a profile photo attached to your Instagram, Snapchat, or Linkedin, you’re considered (in polite terms) an unusual outlier.

I have built a Go package called Showerglass for profile photos. It’s a soothing face filter where you can appreciate the beauty but not fully identify the person. It’s suitable for a wide variety of social applications.

An image of a young woman.
Image credit: https://unsplash.com/photos/tCJ44OIqceU

I believe it’s a good compromise of competing privacy considerations for profile photos. It uses the Delaunay Triangulation algorithm on faces to give the frosted shower-glass effect.

To build it I had to learn the basics of the image and image/draw* package which I will explain below.

GITHUB REPO: Showerglass

What is an image?

It turns out that an image.Image is not what you intuitively thought it was.

It’s just an interface with a function Atthat specifies for a given coordinate what the color should be. You probably imagined an image to be some bitmap data that represented for each x-y position (pixel) what the color is. It need not be. Even a mathematical equation (with no existing backing data) could satisfy an image.Image.

NOTE: The image package does contain structs such as image.NRGBA that implements the Image interface with backing data.

We’ll use this image as our source for the tutorial below.

Source Imagesrc is now an image.Image

Detecting Faces

The pigo package can be used to detect faces. It is 100% written in Go, unlike other packages that bind to OpenCV using cgo.

The objective is to apply the Delaunay Triangulation algorithm to only those regions. Unfortunately, the triangle package only applies to the entire image.

pigo returns a slice dets containing enough information to determine the location of the bounding face rectangles (shown in red).

Location of the “detected faces”

We can use these bounding rectangles to only apply the algorithm to those regions.

Plan of attack

Left-to-Right: source, mask, triangled faces
  1. Copy from the source image only the sub-image of each face.
  2. Apply the Delaunay Triangulation algorithm to each sub-image (referred to as “triangled”).
  3. Assume the face is an ellipse and generate a mask at the same location of each face in the source.
  4. Draw the triangled image through the mask on top of the source image to produce a final image.
  5. Return the final image to the user.

Triangulating each face

We could have applied the Delaunay Triangulation algorithm to the entire source image and used the same mask referred to above. However, the algorithm is computationally expensive.

Instead, we run the algorithm on only the smaller sub-images containing only the faces. We don’t need to copy any other part of the source image so it appears black (the default color).

Triangled image of just faces

Creating a Mask

The mask for the 2 faces in source

We need to create a mask so that we can “draw the faces in the triangled image on top of the source.

A mask is a black and white image. The white region allows the triangled image to be drawn through. The black region blocks the triangled image from being drawn through.

Since the triangled image contains rectangle-shaped images of the faces, we need to make the white regions ellipses to more accurately model the typical shape of a face.

Elliptical Mask

The mask is also an image.Image. If you recall from above, an image.Image need not have backing data. It can be defined by a mathematical equation. In this case, we can create an image where if the (x,y) coordinates are enclosed by the definition of an ellipse, we return white. Otherwise, we return black.

Equation of ellipse centered at (h,k)

See: https://go.dev/blog/image-draw (written by the brother of Terence Tao)

Fitting a Square Peg through a Round Hole

The final step is to draw the triangled image through the mask and on top of the source to create the final desired image.

The draw.DrawMask function provides exactly that functionality.

draw.DrawMask function signature

The documentation might be confusing to understand so let me explain just enough to understand what is going on.

dst is the image.Image that we want src to be drawn over. In our case, dst is the source image and src is the triangled image.

mask is the black and white mask. We are asking that only the regions of src that are in the same location as the mask’s white regions be drawn over dst. The other parameters specify how to align the mask, source, and destination image’s coordinate systems so they are consistent.

Source ImageThe final image with the filter applied

NOTE: To obfuscate the faces better, MaxPoints (algorithm parameter) should have been reduced further.

Sample Code

GITHUB REPO: Showerglass

The TriangleConfig callback function is called for each detected face. You need to return a showerglass.Processor back with MaxPoints and BlurRadius adjusted based on the facearea.

Since some “detected faces” are false positives, you can return nil to not apply any filter to that region.

Calibration

  • A higher MaxPoints means the face looks closer to the original.
  • A lower MaxPoints (except 0) means a more obfuscated face.

Based on the facearea, you need to calibrate MaxPoints to achieve the desired feel. It is as much an art as it is a science.

Resizing

The package has built-in resizing capabilities too!

Final Thoughts

The golang.org/x/image/draw package is a superior drop-in replacement for image/draw.

GITHUB REPO: Showerglass

Other Articles


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK