用opencv做一个头像

最近一直想换个本人的卡通头像,拎着照片去问价钱,居然要收我80块,想了想还是算了,自己动手做一个吧。
首先描绘一个边缘轮廓,然后再填充颜色。由于本人太好看,不太方便拿给大家展示,我还是拿张益达的图像做实例:

def main():
    img = cv2.imread("timg.jpg")
    img_copy = img

    # 灰度处理
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 中值滤波,去除噪声
    img_blur = cv2.medianBlur(img_gray, 5)
    # 自适应阈值二值化,通过阈值提取轮廓
    img_edge = cv2.adaptiveThreshold(img_blur,
                                     255,
                                     cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                     cv2.THRESH_BINARY,
                                     blockSize=9,
                                     C=3)
    # 将灰度图片变成 3 通道,用于后续合并
    img_edge = cv2.cvtColor(img_edge, cv2.COLOR_GRAY2BGR)
    cv2.namedWindow('张益达', cv2.WINDOW_AUTOSIZE)
    cv2.imshow('input_image', img_edge)
    cv2.waitKey(0)
    cv2.destroyWindows()

if __name__ == '__main__':
    main()

得到如下图片:
在这里插入图片描述
嘿,对比原图来看,有点儿感觉了哈。
在这里插入图片描述
上面代码中,cv2.medianBlur(img, ksize)是中值滤波,后面的参数ksize代表内核区域的边长,必须是大于1的奇数,该方法提取内核区域下所有像素的中值,并将中心元素替换位该中值。cv2.adaptiveThreshold(src, maxval, thresh_type, type, Block Size, C)为自适应阈值二值化,其中:
src为输入图片,而且只能输入单通道图像,也就是灰度图。
maxval为当像素值超过了阈值,或者小于阈值(根据type决定)所赋予的值。
type二值化操作的类型,与固定阈值函数相同,包含5种类型:cv2.THRESH_TOZERO;cv2.THRESH_BINARY;cv2.THRESH_TOZERO_INV; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC。
Block Size:图片中分块的大小
C为阈值计算方法中的常数项

就像画画一样,描绘好边缘后,接下来就是上色,我们只需要将原图片的颜色细致度降低即可。我们先用图像金字塔将分辨率降低,然后欧阳那个双边滤波去除噪声,平滑平面区域并保持边缘清晰。然后分辨率降低后图片会变小,因此最后要将图像放大为原来的大小。这部分代码如下:

for _ in range(2)
	# 降低分辨率
    img_copy = cv2.pyrDown(img_copy)
for _ in range(5):
	# 图像平滑,保留边缘,双边滤波
    img_copy = cv2.bilateralFilter(img_copy, d=9, sigmaColor=9, sigmaSpace=7)
img_copy = cv2.resize(img_copy, (img.shape[1], img.shape[0]),
                       interpolation=cv2.INTER_CUBIC)

其中,cv2.bilateralFilter(src, d, sigmaColor, sigmaSpace[, dst[, borderType]])的参数如下:
d过滤时周围每个像素领域的直径
sigmaColor再color space中过滤sigma。参数越大,临近像素将会在越远的地方mix
sigmaSpace在coordinate space中过滤sigma。参数越大,那些颜色足够相近的的颜色的影响越大。

提取出颜色后,我们将轮廓和颜色合并:

 img_cartoon = cv2.bitwise_and(img_copy, img_edge)

cv2.bitwise_and() 是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作:1&1=1,1&0=0,0&1=0,0&0=0
最后得到图像:
在这里插入图片描述
emmmm…感觉还可以用哈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值