圣诞节到了,我偷偷看了一眼,身边的人画像很和谐,我觉得这不正常:圣诞老人没给你戴帽子吗?好吧,既然圣诞老人没有给你戴帽子,那就让无服务器架构给你戴帽子吧。先预览一下外观吧,百度随便找了一张图:加一顶圣诞帽:看到效果后,我们来测试一下功能(如果你只是想玩,可以直接用我的这个接口):url:http://service-8d3fi753-12567...输入:pic,字符串类型,原始图片的base64输出:图片,字符串类型,戴帽子图片的base64基本测试代码(Python3):importbase64importurllib.requestimportjsonwithopen("测试.png",'rb')asf:image=f.read()image_base64=str(base64.b64encode(image),encoding='utf-8')url="https://service-ly70xmyz-1256773370.sh.apigw.tencentcs.com/test/addChristmasHat"data={"pic":image_base64}picture=json.loads(urllib.request.urlopen(urllib.request.Request(url=url,data=json.dumps(data).encode("utf-8")).read().decode("utf-8"))["picture"]imgData=base64.b64decode(picture)withopen('output.png','wb')asf:f.write(imgData)当然有的小伙伴可能想把这个服务部署到自己的云函数中,所以可以参考如下:项目核心代码(Python3函数,部署在云函数上是的):importcv2importdlibimportbase64importjsondefaddHat(img,hat_img):print("分离rgba通道,合成rgb三通道帽子图像,并将其用作a通道??后面的掩码")r,g,b,a=cv2.split(hat_img)rgbHat=cv2.merge((r,g,b))print("dlib人脸关键点检测器,正面人脸检测")predictorPath="shape_predictor_5_face_landmarks.dat"predictor=dlib.shape_predictor(predictorPath)detector=dlib.get_frontal_face_detector()dets=detector(img,1)print("ifdetectedface")如果len(dets)>0:对于dets中的d:x,y,w,h=d.left(),d.top(),d.right()-d.left(),d.bottom()-d.top()print("Keypointdetection,5keypoints")shape=predictor(img,d)print("选择左右眼角的点")point1=shape.part(0)point2=shape.part(2)print("求两点的中心")eyes_center=((point1.x+point2.x)//2,(point1.y+point2.y)//2)print("根据Facesize调整hatsize")factor=1.5resizedHatH=int(round(rgbHat.shape[0]*w/rgbHat.shape[1]*factor))resizedHatW=int(round(rgbHat.shape[1]*w/rgbHat.shape[1]*factor))ifresizedHatH>y:resizedHatH=y-1print("根据脸的大小调整帽子的大小")resizedHat=cv2.resize(rgbHat,(resizedHatW,resizedHatH))print("使用alpha通道作为遮罩")mask=cv2.resize(a,(resizedHatW,resizedHatH))maskInv=cv2.bitwise_not(mask)print("hat相对于人脸框上线的偏移")dh=0bgRoi=img[y+dh-resizedHatH:y+dh,(eyes_center[0]-resizedHatW//3):(eyes_center[0]+resizedHatW//3*2)]print("提取原图ROI中放置帽子的区域")bgRoi=bgRoi.astype(float)maskInv=cv2.merge((maskInv,maskInv,maskInv))alpha=maskInv.astype(float)/255print("相乘前确保两者大小相同(可能因四舍五入不一致)")alpha=cv2.resize(alpha,(bgRoi.shape[1],bgRoi.形状[0]))bg=cv2.multiply(alpha,bgRoi)bg=bg.astype('uint8')print("提取帽子区域")hat=cv2.bitwise_and(resizedHat,cv2.bitwise_not(maskInv))print("确保两者具有相同的添加前的大小(由于四舍五入可能不一致)")hat=cv2.resize(hat,(bgRoi.shape[1],bgRoi.shape[0]))print("添加两个ROI区域")addHat=cv2.add(bg,hat)print("添加帽子区域放回原来的image")img[y+dh-resizedHatH:y+dh,(eyes_center[0]-resizedHatW//3):(eyes_center[0]+resizedHatW//3*2)]=addHatreturnimgdefmain_handler(event,context):try:print("Convertthereceivedbase64imagetopic")imgData=base64.b64decode(json.loads(event["body"])["pic"])withopen('/tmp/picture.png','wb')asf:f.write(imgData)print("读取帽子素材和用户头像")hatImg=cv2.imread("hat.png",-1)userImg=cv2.imread("/tmp/picture.png")output=addHat(userImg,hatImg)cv2.imwrite("/tmp/output.jpg",output)print("读取头像返回给用户,返回inBase64")withopen("/tmp/output.jpg","rb")asf:base64Data=str(base64.b64encode(f.read()),encoding='utf-8')return{"picture":base64Data}除了Exceptionase:return{"error":str(e)}使用方法:下载我打包好的文件:https://serverless-framework-...解压:打开命令行工具,进入项目目录:执行serverless--debug:可能会唤起二维码登录,手机扫码登录即可:部署成功:此时你的接口地址就是返回给你的地址+/add_christmas_hat,比如我的返回地址是:http://service-n5ahp2w4-12567...接口地址是:http://service-n5ahp2w4-12567...大家可以直接在自己的项目中使用这个接口。比如在小程序里上传一张图片,发给这个服务,或者在网页上上传一张图片,发给这个服务,就可以获得Serverless给你的圣诞帽。
