图像处理:图像特效之油画效果

利用OpenCV+python对图片进行处理产生油画的效果

算法可以分为五步:

  • 1、获取图像的灰度(gray)图片
  • 2、设计一个小方框(4x4 or 8x8 or 10x10等),统计每个小方框的像素值
  • 3、将0-255的灰度值划分成几个等级,并把第二步处理的结果映射到所设置的各个等级中,并计数
  • 4、找到每个方框中灰度等级最多的所有的像素,并且求取这些像素的均值
  • 5、用统计出来的平均值来替代原来的像素值

        因为用了很多for循环, 所以,计算复杂,图像处理运行时间较长,可以选用尺寸较小的图片来进行测试,程序还有很多可以优化的地方,再配合一些修图工具(如PS),对图片的细节进行修补,感觉可以裱起来了。 

 

import cv2
import numpy as np

img = cv2.imread('image5.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 3), np.uint8)
pixel_class = 4
section = int(256/pixel_class)
# 用两层for循环来遍历图片的每个数据
for i in range(3, height-3):
    for j in range(3, width-3):
        # 当前程序中定义的灰度等级是4个
        # 定义一个数组来装载这4个等级内的像素个数
        array1 = np.zeros(pixel_class, np.uint8)
        # 当前程序中定义的小方块是6x6的
        for m in range(-3, 3):
            for n in range(-3, 3):
                # p1是对该像素点等级段的划分,用下标表示0-3
                p1 = int(gray[i+m, j+n]/section)
                # 接下来对像素等级进行计数,array1的下标代表像素等级,
                # 值则代表处在该像素等级小方框内像素的个数
                array1[p1] = array1[p1] + 1
        # 接下来判断在这个小方框内哪一个像素段的像素最多
        currentMax = array1[0]
        l = 0  # 这里设置一个l用来记录像素段计数最多的数组下标
        for k in range(0, pixel_class):
            if currentMax < array1[k]:
                currentMax = array1[k]
                l = k
        # 均值处理
        u = v = w = 0
        for m in range(-3, 3):
            for n in range(-3, 3):
                if gray[i+m,j+n] >= (l*section) and gray[i+m, j+n] <= ((l+1)*section):
                    (b, g, r) = img[i+m, j+n]
                    u += b
                    v += g
                    w += r
        u = int(u/array1[l])
        v = int(v/array1[l])
        w = int(w/array1[l])
        dst[i, j] = [u, v, w]
cv2.imshow('dst', dst)
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imwrite('oil_painting.png', dst)

 

​​

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值