四、图片特效

一、灰度处理

  • 使用openCV的imread方法实现
import cv2

img0 = cv2.imread('image0.jpg', 0)
img1 = cv2.imread('image0.jpg', 1)
print(img0.shape)
print(img1.shape)
cv2.imshow('src', img0)
cv2.waitKey(0)

在这里插入图片描述

  • 使用openCV的cvtColor方法实现:cvtColor实现颜色空间的转换
import cv2

img = cv2.imread('image0.jpg', 1)
dst = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 颜色空间转换 1 data 2 BGR gray
cv2.imshow('dst', dst)
cv2.waitKey(0)

  • 利用R=G=B的方式实现:使用(R+G+B)/ 3 赋值给像素点
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
# RGB R=G=B = gray  (R+G+B)/3
dst = np.zeros((height, width, 3), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        (b, g, r) = img[i, j]
        gray = (int(b) + int(g) + int(r)) / 3
        dst[i, j] = np.uint8(gray)
cv2.imshow('dst', dst)
cv2.waitKey(0)

  • 使用心理学公式:r * 0.299 + g * 0.587 + b * 0.114
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height, width, 3), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        (b, g, r) = img[i, j]
        b = int(b)
        g = int(g)
        r = int(r)
        gray = r * 0.299 + g * 0.587 + b * 0.114
        dst[i, j] = np.uint8(gray)
cv2.imshow('dst', dst)
cv2.waitKey(0)

  • 算法优化:浮点数据转换成定点数据;乘除转换成位移计算
    • 这里的系数是按乘以4计算了,如果希望精度更快,可以乘100,1000。。。。。
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
# RGB R=G=B = gray  (R+G+B)/3
dst = np.zeros((height, width, 3), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        (b, g, r) = img[i, j]
        b = int(b)
        g = int(g)
        r = int(r)
        # 浮点转定点:gray = r * 0.299 + g * 0.587 + b * 0.114
        # 乘除转位移:gray = (r*1+g*2+b*1)/4
        gray = (r + (g << 1) + b) >> 2
        dst[i, j] = np.uint8(gray)
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

二、颜色反转

  • 灰度图片的颜色反转:255-当前的灰度值
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 1), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        grayPixel = gray[i, j]
        dst[i, j] = 255 - grayPixel
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

  • 彩色图片的颜色反转:255-当前通道的颜色值
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height, width, 3), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        (b, g, r) = img[i, j]
        dst[i, j] = (255 - b, 255 - g, 255 - r)
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

三、马赛克

  • 图片实现马赛克的原理:将一片区局域中的所有的像素保持一致
    • 例如:我们想给一个10 * 10的区域打上马赛克
    • 那么我们取到10*10中左上角点的像素值,替换掉10 * 10的100个像素点
    • 这样就实现了马赛克效果
import cv2

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
for m in range(100, 300):
    for n in range(100, 200):
        # pixel ->10*10
        if m % 10 == 0 and n % 10 == 0:
            for i in range(0, 10):
                for j in range(0, 10):
                    (b, g, r) = img[m, n]
                    img[i + m, j + n] = (b, g, r)
cv2.imshow('dst', img)
cv2.waitKey(0)

在这里插入图片描述

四、毛玻璃

  • 毛玻璃的实现原理
    • 马赛克效果我们使用的是左上角的像素点来替换掉其他像素点
    • 而毛玻璃是使用随机的像素点来替换掉当前的像素点
import cv2
import numpy as np
import random

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height, width, 3), np.uint8)
mm = 8  # 水平方向上和竖直方向都有可能是8
for m in range(0, height - mm):  # -mm是为了防止矩阵越界,同时这里减了mm,所以生成的时候下方和右方会有很色的边框
    for n in range(0, width - mm):
        index = int(random.random() * 8)  # random.random()是0-1,所以index是0-8
        (b, g, r) = img[m + index, n + index]
        dst[m, n] = (b, g, r)
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

五、图片融合

  • 2张图片融合的计算公式:dst = src1a+src2(1-a),其中a指的是alpha系数
import cv2

img0 = cv2.imread('image0.jpg', 1)
img1 = cv2.imread('image1.jpg', 1)
imgInfo = img0.shape
height = imgInfo[0]
width = imgInfo[1]
# ROI感兴趣范围,这个要比2张图片的范围都小
roiH = int(height / 2)
roiW = int(width / 2)
img0ROI = img0[0:roiH, 0:roiW]
img1ROI = img1[0:roiH, 0:roiW]
# dst
dst = cv2.addWeighted(img0ROI, 0.5, img1ROI, 0.5, 0)  # add src1*a+src2*(1-a)
# 1 src1 2 a 3 src2 4 1-a
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

六、边缘检测与浮雕效果

1 - 边缘检测

  • 什么是边缘检测:边缘检测的效果有点类似素描,边缘检测的实质是图像的卷积计算
  • openCV的API方式实现边缘检测的步骤
    • 灰度处理
    • 高斯滤波
    • canny方法
import cv2

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src', img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 灰度处理
imgG = cv2.GaussianBlur(gray, (3, 3), 0)  # 高斯滤波
dst = cv2.Canny(img, 50, 50)  # 图片卷积——》th,双阀值
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

  • 源码形式实现边缘检测:sobel算法实现,这里会涉及到如下几个概念
  • sobel算法的算子模板:水平方向、垂直方向
水平方向     垂直方向
[1 2 1          [ 1 0 -1
 0 0 0            2 0 -2
-1 -2 -1 ]        1 0 -1 ]
  • 图片卷积:假设1张图片中的4个像素点为[1 2 3 4],当前的模板是[a b c d],那么卷积的结果:a1+b2+c3+d4 = dst
    • a:竖直方向上的梯度 -> 水平方向上的算子与图片卷积的结果
    • b:水平方向上的梯度 -> 垂直方向上的算子与图片卷积的结果
    • f:阀值,f = sqrt(a * a + b * b)
    • th:判决门限
  • 阀值判决:f > th 是边缘,否则是非边缘
import cv2
import numpy as np
import math

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src', img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 1), np.uint8)
for i in range(0, height - 2):
    for j in range(0, width - 2):
        gy = gray[i, j] * 1 + gray[i, j + 1] * 2 + gray[i, j + 2] * 1 - gray[i + 2, j] * 1 - gray[i + 2, j + 1] * 2 - \
             gray[i + 2, j + 2] * 1
        gx = gray[i, j] + gray[i + 1, j] * 2 + gray[i + 2, j] - gray[i, j + 2] - gray[i + 1, j + 2] * 2 - gray[
            i + 2, j + 2]
        grad = math.sqrt(gx * gx + gy * gy)
        if grad > 50:  # 50为域值
            dst[i, j] = 255
        else:
            dst[i, j] = 0
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

2 - 浮雕效果

  • 浮雕效果计算公式:每一个新的像素值等于相邻像素的像素值之差加上一个恒定值(比如150)
    • newP = gray0 - gray1 + 150
    • 这里加上150是为了增强图片的浮雕灰度等级
    • 相邻像素相减是为了突出灰度的突片及边缘特征
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 1), np.uint8)
for i in range(0, height):
    for j in range(0, width - 1):
        grayP0 = int(gray[i, j])
        grayP1 = int(gray[i, j + 1])
        newP = grayP0 - grayP1 + 150
        if newP > 255:
            newP = 255
        if newP < 0:
            newP = 0
        dst[i, j] = newP
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

七、颜色映射

  • 颜色映射最简单的实现方式
    • 做一个很大的查找表,根据原始图像的rgb值根据查找表查找一组新的rgb,用新的rgb代替原来像素值
    • 也可以用一些简单的公式完成颜色映射,利用公式的方法可能无法表示一些更为复杂的效果
  • 案例:蓝色与绿色增强
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
cv2.imshow('src', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height, width, 3), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        (b, g, r) = img[i, j]
        b = b * 1.5
        g = g * 1.3
        if b > 255:
            b = 255
        if g > 255:
            g = 255
        dst[i, j] = (b, g, r)
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

八、油画效果

  • 油画效果实现步骤
    • ①.gray 灰度化
    • ②.将图片分割为若干个小方块。统计这些小方块中每个像素的灰度值,比如7 * 7 ,10 * 10
    • ③.将0-255划分段,并将第二步的映射到对应段范围中:如划分4个段,每个段有64个等级。0-63 第1段;64-127第2段
    • ④.例如:这时有一个像素点.灰度值是10,那么他就在0-63这个点
      • 找到每个方块中灰度等级最多的所有像素,count 并求取这些像素的均值
      • 用统计出来的平均值,替代原来的像素值
import cv2
import numpy as np

img = cv2.imread('image0.jpg', 1)
cv2.imshow('src', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 3), np.uint8)
# 这里从-4开始,所以边界值要从4开始
for i in range(4, height - 4):
    for j in range(4, width - 4):
        array1 = np.zeros(8, np.uint8)
        for m in range(-4, 4):  # 定义8*8的小方块
            for n in range(-4, 4):
                p1 = int(gray[i + m, j + n] / 32)  # 灰度等级划分为8个段,每个为256/8
                array1[p1] = array1[p1] + 1
        currentMax = array1[0]
        l = 0  # 记录是哪个段
        for k in range(0, 8):  # 求最大值
            if currentMax < array1[k]:
                currentMax = array1[k]
                l = k
        # 简化 均值
        for m in range(-4, 4):
            for n in range(-4, 4):
                # l是处于哪一个灰度段,32是它的灰度等级
                # 小于等于下一个灰度段,保证处于范围之内
                if gray[i + m, j + n] >= (l * 32) and gray[i + m, j + n] <= ((l + 1) * 32):
                    (b, g, r) = img[i + m, j + n]
        dst[i, j] = (b, g, r)
cv2.imshow('dst', dst)
cv2.waitKey(0)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无休止符

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值