- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章基于Opencv制作的美颜相机带你领略美颜特效的效果由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
。
现在每一次出门,女友就喜欢拍照!BUT 嫌弃我给拍的照片角度不对,采光不好....... 。
。
总之一大堆理由,啥时候让我拍照的水平能有美颜相机三分之一的效果就好! 。
果然都是锻炼出来的,至少现在我能看出来朋友圈哪些小姐姐批没批过照片。 。
。
逃不掉 。
逃不掉啊,为了摆脱这种局面―― 。
立马给女友写了一款简易版本的美颜相机给她偷偷的用!这样子就不担心被锤了。机智如我.jpg 。
。
。
环境安装:
dlib库的安装 本博客提供三种方法进行安装 T1方法:pip install dlib 此方法是需要在你安装cmake、Boost环境的计算机使用 。T2方法:conda install -c menpo dlib=18.18此方法适合那些已经安装好conda库的环境的计算机使用。T3方法:pip install dlib-19.8.1-cp36-cp36m-win_amd64.whl dlib库的whl文件――dlib-19.7.0-cp36-cp36m-win_amd64.rar dlib-19.3.1-cp35-cp35m-win_amd64.whl
cv2库安装方法: pip install opencv-python
人脸五官,坐标、进行高斯模糊处理等等.
# 五官class Organ(): def __init__(self, img, img_hsv, temp_img, temp_hsv, landmarks, name, ksize=None): self.img = img self.img_hsv = img_hsv self.landmarks = landmarks self.name = name self.get_rect() self.shape = (int(self.bottom-self.top), int(self.right-self.left)) self.size = self.shape[0] * self.shape[1] * 3 self.move = int(np.sqrt(self.size/3)/20) self.ksize = self.get_ksize() self.patch_img, self.patch_hsv = self.get_patch(self.img), self.get_patch(self.img_hsv) self.set_temp(temp_img, temp_hsv) self.patch_mask = self.get_mask_relative() # 获取定位方框 def get_rect(self): y, x = self.landmarks[:, 1], self.landmarks[:, 0] self.top, self.bottom, self.left, self.right = np.min(y), np.max(y), np.min(x), np.max(x) # 获得ksize,高斯模糊处理的参数 def get_ksize(self, rate=15): size = max([int(np.sqrt(self.size/3)/rate), 1]) size = (size if size%2==1 else size+1) return(size, size) # 截取局部切片 def get_patch(self, img): shape = img.shape return img[np.max([self.top-self.move, 0]): np.min([self.bottom+self.move, shape[0]]), np.max([self.left-self.move, 0]): np.min([self.right+self.move, shape[1]])] def set_temp(self, temp_img, temp_hsv): self.img_temp, self.hsv_temp = temp_img, temp_hsv self.patch_img_temp, self.patch_hsv_temp = self.get_patch(self.img_temp), self.get_patch(self.hsv_temp) # 确认 def confirm(self): self.img[:], self.img_hsv[:] = self.img_temp[:], self.hsv_temp[:] # 更新 def update_temp(self): self.img_temp[:], self.hsv_temp[:] = self.img[:], self.img_hsv[:] # 勾画凸多边形 def _draw_convex_hull(self, img, points, color): points = cv2.convexHull(points) cv2.fillConvexPoly(img, points, color=color) # 获得局部相对坐标遮盖 def get_mask_relative(self, ksize=None): if ksize == None: ksize = self.ksize landmarks_re = self.landmarks.copy() landmarks_re[:, 1] -= np.max([self.top-self.move, 0]) landmarks_re[:, 0] -= np.max([self.left-self.move, 0]) mask = np.zeros(self.patch_img.shape[:2], dtype=np.float64) self._draw_convex_hull(mask, landmarks_re, color=1) mask = np.array([mask, mask, mask]).transpose((1, 2, 0)) mask = (cv2.GaussianBlur(mask, ksize, 0) > 0) * 1.0 return cv2.GaussianBlur(mask, ksize, 0)[:] # 获得全局绝对坐标遮盖 def get_mask_abs(self, ksize=None): if ksize == None: ksize = self.ksize mask = np.zeros(self.img.shape, dtype=np.float64) patch = self.get_patch(mask) patch[:] = self.patch_mask[:] return mask
主要美颜效果进行的处理如下:
# 美白 def whitening(self, rate=0.15, confirm=True): if confirm: self.confirm() self.patch_hsv[:, :, -1] = np.minimum(self.patch_hsv[:, :, -1]+self.patch_hsv[:, :, -1]*self.patch_mask[:, :, -1]*rate, 255).astype("uint8") self.img[:]=cv2.cvtColor(self.img_hsv, cv2.COLOR_HSV2BGR)[:] self.update_temp() else: self.patch_hsv_temp[:] = cv2.cvtColor(self.patch_img_temp, cv2.COLOR_BGR2HSV)[:] self.patch_hsv_temp[:, :, -1] = np.minimum(self.patch_hsv_temp[:, :, -1]+self.patch_hsv_temp[:, :, -1]*self.patch_mask[:, :, -1]*rate, 255).astype("uint8") self.patch_img_temp[:] = cv2.cvtColor(self.patch_hsv_temp, cv2.COLOR_HSV2BGR)[:] # 提升鲜艳度 def brightening(self, rate=0.3, confirm=True): patch_mask = self.get_mask_relative((1, 1)) if confirm: self.confirm() patch_new = self.patch_hsv[:, :, 1]*patch_mask[:, :, 1]*rate patch_new = cv2.GaussianBlur(patch_new, (3, 3), 0) self.patch_hsv[:, :, 1] = np.minimum(self.patch_hsv[:, :, 1]+patch_new, 255).astype("uint8") self.img[:]=cv2.cvtColor(self.img_hsv, cv2.COLOR_HSV2BGR)[:] self.update_temp() else: self.patch_hsv_temp[:] = cv2.cvtColor(self.patch_img_temp, cv2.COLOR_BGR2HSV)[:] patch_new = self.patch_hsv_temp[:, :, 1]*patch_mask[:, :, 1]*rate patch_new = cv2.GaussianBlur(patch_new, (3, 3), 0) self.patch_hsv_temp[:, :, 1] = np.minimum(self.patch_hsv[:, :, 1]+patch_new, 255).astype("uint8") self.patch_img_temp[:] = cv2.cvtColor(self.patch_hsv_temp, cv2.COLOR_HSV2BGR)[:] # 磨平 def smooth(self, rate=0.6, ksize=None, confirm=True): if ksize == None: ksize=self.get_ksize(80) index = self.patch_mask > 0 if confirm: self.confirm() patch_new = cv2.GaussianBlur(cv2.bilateralFilter(self.patch_img, 3, *ksize), ksize, 0) self.patch_img[index] = np.minimum(rate*patch_new[index]+(1-rate)*self.patch_img[index], 255).astype("uint8") self.img_hsv[:] = cv2.cvtColor(self.img, cv2.COLOR_BGR2HSV)[:] self.update_temp() else: patch_new = cv2.GaussianBlur(cv2.bilateralFilter(self.patch_img_temp, 3, *ksize), ksize, 0) self.patch_img_temp[index] = np.minimum(rate*patch_new[index]+(1-rate)*self.patch_img_temp[index], 255).astype("uint8") self.patch_hsv_temp[:] = cv2.cvtColor(self.patch_img_temp, cv2.COLOR_BGR2HSV)[:] # 锐化 def sharpen(self, rate=0.3, confirm=True): patch_mask = self.get_mask_relative((3, 3)) kernel = np.zeros((9, 9), np.float32) kernel[4, 4] = 2.0 boxFilter = np.ones((9, 9), np.float32) / 81.0 kernel = kernel - boxFilter index = patch_mask > 0 if confirm: self.confirm() sharp = cv2.filter2D(self.patch_img, -1, kernel) self.patch_img[index] = np.minimum(((1-rate)*self.patch_img)[index]+sharp[index]*rate, 255).astype("uint8") self.update_temp() else: sharp = cv2.filter2D(self.patch_img_temp, -1, kernel) self.patch_img_temp[:] = np.minimum(self.patch_img_temp+self.patch_mask*sharp*rate, 255).astype("uint8") self.patch_hsv_temp[:] = cv2.cvtColor(self.patch_img_temp, cv2.COLOR_BGR2HSV)[:] # 额头class ForeHead(Organ): def __init__(self, img, img_hsv, temp_img, temp_hsv, landmarks, mask_organs, name, ksize=None): self.mask_organs = mask_organs super(ForeHead, self).__init__(img, img_hsv, temp_img, temp_hsv, landmarks, name, ksize) # 获得局部相对坐标mask def get_mask_relative(self, ksize=None): if ksize == None: ksize = self.ksize landmarks_re = self.landmarks.copy() landmarks_re[:, 1] -= np.max([self.top-self.move, 0]) landmarks_re[:, 0] -= np.max([self.left-self.move, 0]) mask = np.zeros(self.patch_img.shape[:2], dtype=np.float64) self._draw_convex_hull(mask, landmarks_re, color=1) mask = np.array([mask, mask, mask]).transpose((1, 2, 0)) mask = (cv2.GaussianBlur(mask, ksize, 0) > 0) * 1.0 patch_organs = self.get_patch(self.mask_organs) mask= cv2.GaussianBlur(mask, ksize, 0)[:] mask[patch_organs>0] = (1-patch_organs[patch_organs>0]) return mask # 脸类class Face(Organ): def __init__(self, img, img_hsv, temp_img, temp_hsv, landmarks, index): self.index = index # 五官:下巴、嘴、鼻子、左右眼、左右耳 self.organs_name = ["jaw", "mouth", "nose", "left_eye", "right_eye", "left_brow", "right_brow"] # 五官标记点 self.organs_point = [list(range(0, 17)), list(range(48, 61)), list(range(27, 35)), list(range(42, 48)), list(range(36, 42)), list(range(22, 27)), list(range(17, 22))] self.organs = {name: Organ(img, img_hsv, temp_img, temp_hsv, landmarks[points], name) for name, points in zip(self.organs_name, self.organs_point)} # 额头 mask_nose = self.organs["nose"].get_mask_abs() mask_organs = (self.organs["mouth"].get_mask_abs()+mask_nose+self.organs["left_eye"].get_mask_abs()+self.organs["right_eye"].get_mask_abs()+self.organs["left_brow"].get_mask_abs()+self.organs["right_brow"].get_mask_abs()) forehead_landmark = self.get_forehead_landmark(img, landmarks, mask_organs, mask_nose) self.organs["forehead"] = ForeHead(img, img_hsv, temp_img, temp_hsv, forehead_landmark, mask_organs, "forehead") mask_organs += self.organs["forehead"].get_mask_abs() # 人脸的完整标记点 self.FACE_POINTS = np.concatenate([landmarks, forehead_landmark]) super(Face, self).__init__(img, img_hsv, temp_img, temp_hsv, self.FACE_POINTS, "face") mask_face = self.get_mask_abs() - mask_organs self.patch_mask = self.get_patch(mask_face) # 计算额头坐标 def get_forehead_landmark(self, img, face_landmark, mask_organs, mask_nose): radius = (np.linalg.norm(face_landmark[0]-face_landmark[16])/2).astype("int32") center_abs = tuple(((face_landmark[0]+face_landmark[16])/2).astype("int32")) angle = np.degrees(np.arctan((lambda l:l[1]/l[0])(face_landmark[16]-face_landmark[0]))).astype("int32") mask = np.zeros(mask_organs.shape[:2], dtype=np.float64) cv2.ellipse(mask, center_abs, (radius, radius), angle, 180, 360, 1, -1) # 剔除与五官重合部分 mask[mask_organs[:, :, 0]>0]=0 # 根据鼻子的肤色判断真正的额头面积 index_bool = [] for ch in range(3): mean, std = np.mean(img[:, :, ch][mask_nose[:, :, ch]>0]), np.std(img[:, :, ch][mask_nose[:, :, ch]>0]) up, down = mean+0.5*std, mean-0.5*std index_bool.append((img[:, :, ch]<down)|(img[:, :, ch]>up)) index_zero = ((mask>0)&index_bool[0]&index_bool[1]&index_bool[2]) mask[index_zero] = 0 index_abs = np.array(np.where(mask>0)[::-1]).transpose() landmark = cv2.convexHull(index_abs).squeeze() return landmark # 化妆器class Makeup(): def __init__(self, predictor_path="./predictor/shape_predictor_68_face_landmarks.dat"): self.photo_path = [] self.predictor_path = predictor_path self.faces = {} # 人脸检测与特征提取 self.detector = dlib.get_frontal_face_detector() self.predictor = dlib.shape_predictor(self.predictor_path) # 人脸定位和特征提取 # img为numpy数组 # 返回值为人脸特征(x, y)坐标的矩阵 def get_faces(self, img, img_hsv, temp_img, temp_hsv, name, n=1): rects = self.detector(img, 1) if len(rects) < 1: print("[Warning]:No face detected...") return None return {name: [Face(img, img_hsv, temp_img, temp_hsv, np.array([[p.x, p.y] for p in self.predictor(img, rect).parts()]), i) for i, rect in enumerate(rects)]} # 读取图片 def read_img(self, fname, scale=1): img = cv2.imdecode(np.fromfile(fname, dtype=np.uint8), -1) if not type(img): print("[ERROR]:Fail to Read %s" % fname) return None return img def read_and_mark(self, fname): img = self.read_img(fname) img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) temp_img, temp_hsv = img.copy(), img_hsv.copy() return img, temp_img, self.get_faces(img, img_hsv, temp_img, temp_hsv, fname)
效果如下:
嘿嘿――小姐姐美颜之后是不是白了很多吖! 。
。
本次文章就到这里啦!如需完整的打包好的项目源码基地见:#私信小编06#即可免费领取! 。
记得关注、评论、点赞三连哦~ 。
到此这篇关于基于Opencv制作的美颜相机带你领略美颜特效的效果的文章就介绍到这了,更多相关Opencv 美颜相机内容请搜索我以前的文章或继续浏览下面的相关文章希望大家以后多多支持我! 。
原文链接:https://blog.csdn.net/weixin_55822277/article/details/120333550 。
最后此篇关于基于Opencv制作的美颜相机带你领略美颜特效的效果的文章就讲到这里了,如果你想了解更多关于基于Opencv制作的美颜相机带你领略美颜特效的效果的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
有人能给我一些代码示例,了解如何从相机捕获“完整”图像,然后在“startActivityForResult”中将其转换为字节,以及显示在 imageView 中的位图。任何帮助将不胜感激。 山姆 最
我有一个带有两个圆的组,当我用平移过渡移动其中一个时,我应该看到静止的一个保持在中心(位于场景图的中间),而另一个移动。取而代之的是,“摄像机”跟随移动的圆圈,使其看起来好像都在分开。 有没有一种方法
我希望停止 Phonegap 将图片保存到 iOS 上的相机胶卷。 我发现了一种可能的解决方案,但我不太喜欢它。该解决方案需要通过删除这行代码来 fork phonegap API。 UIImageW
我最近开始使用 JOGL,我知道如何在 Canvas 上创建和绘制对象,但我找不到有关如何设置和旋转相机的教程或说明。我只找到了源代码,但由于我对此很陌生,所以它没有太大帮助。 有人知道一个好的教程或
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 8 年前。 Improve this ques
我想实现这样的目标: 因此,您捕获和处理的唯一内容是矩形中的区域。我需要这个,因为我想做一些 OCR 而我不想要整个屏幕。 最佳答案 也许可以帮助您这个来源,(在相机预览顶部绘制一个边界框以捕获部分图
我正在开发一个 Android 应用程序,我希望我的应用程序能够拍照并显示它们。我的问题是它制作了图片,将它存储在 SD 卡上但没有在我的应用程序中显示它,ImageView 保持空白。这是我的代码:
我正在研究 Android 相机教程,SDK 11。出于某种原因,我在 handleCameraPhoto() 中得到了一个空指针。我唯一看到的是“无法将结果 ResultInfo{who=null,
我一直在尝试实现此代码,我在其中从相机捕获图像并将其显示在我的图像查看器中,然后可以将其设置为墙纸。它在我的模拟器中运行良好,但在我的手机上,当我拍摄图像并单击“确定”时,它会强制关闭。有什么帮助吗?
我想将预览中的某些像素更改为比其余像素暗一点。假设我希望预览的上半部分比预览的下半部分暗一点。 我试图像这样使用 setPreviewCallback: camera.setPreviewCallba
我想为我的应用程序启用相机/照片库设置。我可以显示警报以编程方式启用这些吗就像应用程序启动时一样。我已附上图片以显示我希望看到我的应用程序的类似设置 对于我的应用程序,我没有看到此设置。 我的问题是这
所以我正在开发类似于相机应用程序的东西。它在原生 OpenGL 纹理上绘制实时相机预览。如果按下按钮,则会以原始形式捕获静态图像(可能比实时预览分辨率更高)。 这是我的代码的大纲。为了清楚起见,我没有
我想在我的 Android 应用程序中启动相机 Activity ,我知道该怎么做。我想问一下当相机 Activity 结束时,我如何检查它是否是用户拍摄的照片或视频? 已更新 我有一个对话框,其中询
我在横向模式下有自定义全屏摄像头。设备尺寸为 1024 x 600。 支持的预览尺寸列表 宽 x 高 176 x 144 320 x 240 352 x 288 528 x 432 640 x 480
请看下图!! 所以在这张图片中...您可以看到底部的弹出窗口,当用户“点击”“相机”按钮时,它会为用户提供 3 个选项。 那是什么观点?它是一个模态视图 Controller ,在选择一个选项时被关闭
我发布了一个应用程序,其中一项基本功能是允许用户拍照,然后将该照片保存在其外部存储上的特定文件夹中。 一切似乎都运行良好,但我现在收到两份报告,声称在拍照后单击“完成”退出相机(并返回到 Activi
我在尝试实时更换相机时遇到问题,它适用于本地视频,但远程人员看不到新相机,但仍然可以看到旧相机。我试图停止流并再次初始化,但仍然无法正常工作。这只是我的一些代码。 我到处搜索,但找不到解决方案。有人可
一个简单但非常复杂的问题:为 Flutter 相机添加点击对焦功能的最佳方法是什么? 我在整个万维网上搜索了优雅的解决方案,但一无所获。 你有想法吗? 最佳答案 我可能会迟到,但你可以试试 adv_c
我正在尝试使用 gluLookAt 方法设置 3D 相机。所以我有一个 10x10x10 的立方体,现在我想在那个立方体内移动相机。我有这样的事情: gluLookAt( camera->x,came
我赠送一个 UIImagePickerController在我的应用程序中通过在 sheet 中呈现逻辑修饰符。简而言之,以下三种类型处理显示和关闭 UIImagePickerController 的
我是一名优秀的程序员,十分优秀!