Building a Face‑Recognition Meme Generator with Python and Weex
This guide shows how to create a face‑recognition meme generator by capturing photos with Weex’s WindVane module, sending them to a lightweight Python HTTP server that uses dlib for landmark detection, alignment, masking and tone correction, and accelerating the process with loky multiprocessing and image down‑sampling.
After the Double‑Eleven shopping festival, a meme‑making activity was launched on Xianyu. This article explains how to quickly build a face‑recognition based meme generator using Python on the server side and Weex on the front end.
1. Front‑end Setup
The front‑end consists of two parts: taking a photo and generating the meme.
1.1 Photo Capture
We use the WindVane camera module, which works only in a Weex environment. The photo‑capture and upload steps must be called separately. The following code shows the typical call sequence:
var params = {
type: '0',
};
window.WindVane.call('WVCamera', 'takePhoto', params, function(e) {
var uploadParams = {
path: e.localPath,
v: '2.0',
bizCode: 'mtopupload'
};
setTimeout(function() {
window.WindVane.call('WVCamera', 'confirmUploadPhoto', uploadParams, function(e) {
alert('upload success: ' + JSON.stringify(e));
}, function(e) {
alert('upload failure: ' + JSON.stringify(e));
});
}, 20);
}, function(e) {
alert('takePhoto failure: ' + JSON.stringify(e));
});1.2 Meme Generation
The backend API receives the photo URL and a template ID, creates the meme, and returns the meme URL for rendering.
2. Server‑side Setup
The server is built with pure Python using SocketServer and BaseHTTPServer . A simple threaded HTTP server is created as follows:
import BaseHTTPServer as webservice
from SocketServer import ThreadingMixIn
from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
if __name__ == '__main__':
serverAddress = ('', PORT)
server = ThreadingHttpServer(serverAddress, RequestHandler)
server.serve_forever()
class RequestHandler(webservice.BaseHTTPRequestHandler):
def do_GET(self):
# business logic here
passWhen an HTTP request arrives, do_GET is invoked to handle the business logic.
3. Algorithm Choice
The face‑fusion process is divided into four steps:
Face detection
Face alignment
Extract facial landmarks and blend into the meme template
Adjust facial tone
3.1 Face Detection (dlib)
We use dlib to detect 68 facial landmarks. Example code:
# Initialize dlib
import dlib
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(PREDICTOR_PATH)
def get_landmarks(im):
rects = detector(im, 1)
if len(rects) > 1:
raise TooManyFaces
if len(rects) == 0:
raise NoFaces
return numpy.matrix([[p.x, p.y] for p in predictor(im, rects[0]).parts()])3.2 Face Alignment
After obtaining the landmark matrices of two faces, we compute a rotation matrix via SVD and apply an affine transformation:
def warp_im(im, M, dshape):
output_im = numpy.zeros(dshape, dtype=im.dtype)
cv2.warpAffine(im, M[:2], (dshape[1], dshape[0]), dst=output_im, borderMode=cv2.BORDER_TRANSPARENT, flags=cv2.WARP_INVERSE_MAP)
return output_im3.3 Feature Extraction & Mask Creation
Key facial regions (eyes, eyebrows, nose, mouth) are combined into a convex polygon, filled with cv2.fillConvexPoly to create a mask. The mask is feathered and blended with the meme template.
3.4 Tone Adjustment
We convert the blended face to grayscale and apply gamma correction to enhance contrast:
def gamma_trans(img, gamma):
gamma_table = [numpy.power(x/255.0, gamma)*255.0 for x in range(256)]
gamma_table = numpy.round(numpy.array(gamma_table)).astype(numpy.uint8)
return cv2.LUT(img, gamma_table)4. Algorithm Optimization
Two optimizations are applied:
Multiprocessing using the loky library to parallelize heavy image‑processing tasks.
Compressing the detection region (down‑sampling the image before dlib processing) to reduce computation.
Multiprocessing example:
import loky
from loky import get_reusable_executor
executor = get_reusable_executor(max_workers=work_thread, timeout=60)
result = executor.map(do_func, params)
while True:
re = result.next()
# handle resultNote: dlib initialization must be placed inside the multiprocessing function; otherwise it raises a “no safe” error. Also, Python 2 users should avoid the standard Process library as it conflicts with dlib.
Conclusion
The complete implementation demonstrates how to combine front‑end Weex components, a Python HTTP server, and dlib‑based face processing to create a custom meme activity. Performance and visual quality can still be further optimized.
Xianyu Technology
Official account of the Xianyu technology team
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.