OpenCV学习——图像特效

39 篇文章 2 订阅
3 篇文章 1 订阅

OpenCV学习——图像特效

0. 版本信息

产品版本
Python3.7
Anaconda4.8.3
Jupyter6.0.3
OpenCV3.4.2

1. 导包

import cv2
import numpy as np
import random
import math

原图

2. 灰度图

  • 直接读取灰度图
    # 1是读取彩色, 0是读取灰度
    gray_img = cv2.imread("./test03.jpg", 0)
    # gray_img = cv2.imread("./test03.jpg", 1)
    
    cv2.imshow("gray", gray_img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
  • 颜色模式转换
    img = cv2.imread("./test03.jpg", 1)
    
    # 第二个参数是转换方式
    dst_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
  • 手动转换1
    # 原理:当BGR中 B=G=R , 那么是灰度图
    
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 改变每个像素点
    for i in range(0, height):
        for j in range(0, width):
            # 此处采用均值
            img[i, j] = img[i, j].mean()
            
    cv2.imshow("img", img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
  • 手动转换2
    # 原理:gray = R*0.299 + G*0.587 + B*0.114
    
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 改变每个像素点
    for i in range(0, height):
        for j in range(0, width):
            b, g, r = img[i, j]
            gray = int(b * 0.114) + int(g * 0.587) + int(r * 0.299)
            img[i, j] = np.uint8(gray)
            
    cv2.imshow("img", img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
    图片14

3. 颜色反转

  • 灰度图-颜色反转
    # 灰度图-颜色反转
    
    gray_img = cv2.imread("./test03.jpg", 0)
    height, width = gray_img.shape
    
    # 改变每个像素点
    for i in range(0, height):
        for j in range(0, width):
            gray_img[i, j] = 255 - gray_img[i, j]
            
    cv2.imshow("gray_img", gray_img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
    图片15
  • 彩色图-颜色反转
    # 彩色图-颜色反转
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 改变每个像素点
    for i in range(0, height):
        for j in range(0, width):
            img[i, j] = 255 - img[i, j]
            
    cv2.imshow("img", img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
    图片16

4. 马赛克效果

img = cv2.imread("./test03.jpg", 1)

# 每10x10的范围选取首个像素点作为其他所有点的颜色
# step步长决定了马赛克的粗细
step = 10
for i in range(180, 310, step):
    for j in range(50, 180, step):
        for y in range(0, step):
            for x in range(0, step):
                img[i + y, j + x] = img[i, j]

cv2.imshow("img", img)
if cv2.waitKey(0) == ord("q"):
    cv2.destroyAllWindows()

图片17

5. 毛玻璃效果

img = cv2.imread("./test03.jpg", 1)
height, width, channels = img.shape

# 对于每个点随机取其右下10x10范围的一个点
# mm是取值范围,越大越广
mm = 10
for i in range(0, height):
    for j in range(0, width):
        # 随机取点
        r = int(random.random() * mm)
        r_i, r_j = i + r, j + r
        # 处理越界点
        if r_i >= height:
            r_i = height - 1
        elif r_i < 0:
            r_i = 0 
        if r_j >= width:
            r_j = width - 1
        elif r_j < 0:
            r_j = 0
        # 修改像素点
        img[i, j] = img[r_i, r_j]

cv2.imshow("img", img)
if cv2.waitKey(0) == ord("q"):
    cv2.destroyAllWindows()

图片18

6. 图片融合

# 图片融合
# dst = src1 * a + src2 * (1 - a)

img1 = cv2.imread("./test03.jpg", 1)
img2 = cv2.imread("./test02.jpg", 1)

# 融合系数
a = 0.3

# ROI 选取300x300的兴趣区域
img1_roi = img1[100:400, 100:400]
img2_roi = img2[200:500, 200:500]

# 开始融合
# 方式1
# img = cv2.addWeighted(img1_roi, 0.3, img2_roi, 0.7, 0)
# 方式2
img = np.zeros((300, 300, 3), np.uint8)
for i in range(0, 300):
    for j in range(0, 300):
        img[i, j] = img1_roi[i, j] * a + img2_roi[i, j] * (1 - a)
        
cv2.imshow("img", img)
if cv2.waitKey(0) == ord("q"):
    cv2.destroyAllWindows()

图片19

7. 边缘检测

  • canny边缘检测
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 1 gray
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 2 gauss 高斯滤波
    gauss_img = cv2.GaussianBlur(gray_img, (3, 3), 0)
    # 3 canny
    canny_img = cv2.Canny(gauss_img, 50, 50)
    
    cv2.imshow("canny_img", canny_img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
    图片20
  • sobel边缘检测
    img = cv2.imread("./test03.jpg", 1)
    height, width, channels = img.shape
    
    # 灰度gray
    gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    # 1. 算子模板 卷积核
    y_core = [[1, 2, 1], 
              [0, 0, 0], 
              [-1, -2, -1]]
    x_core = [[1, 0, -1], 
              [2, 0, -2], 
              [1, 0, -1]]
    
    # 开始处理
    dst_img = np.zeros((height, width, 1), np.uint8)
    for i in range(0, height - 2):
        for j in range(0, width - 2):
            # 2. 图片卷积 x y
            # 将当前点右下3x3的范围与卷积核相乘,再求和
            gradient_y = 0
            gradient_x = 0
            for m in range(0, 3):
              for n in range(0, 3):
                  gradient_y += gray_img[i + m, j + n] * y_core[m][n]
                  gradient_x += gray_img[i + m, j + n] * x_core[m][n]
            # gradient
            gradient = math.sqrt(gradient_y ** 2 + gradient_x ** 2)
            # 3. 阈值判决
            dst_img[i, j] = 255 if gradient > 50 else 0
            
    cv2.imshow("dst_img", dst_img)
    if cv2.waitKey(0) == ord("q"):
        cv2.destroyAllWindows()
    
    图片21

8. 浮雕效果

# 读取灰度图
gray_img = cv2.imread("./test03.jpg", 0)
height, width = gray_img.shape

dst_img = np.zeros((height, width, 1), np.uint8)
for i in range(0, height):
    for j in range(0, width - 1):
        # 当前点和右边一个点相减,再加150
        new_pixel = int(gray_img[i, j]) - int(gray_img[i, j+1]) + 150
        if new_pixel > 255:
            new_pixel = 255
        elif new_pixel < 0:
            new_pixel = 0
        dst_img[i, j] = new_pixel
        
cv2.imshow("dst_img", dst_img)
if cv2.waitKey(0) == ord("q"):
    cv2.destroyAllWindows()

图片22

9. 油画效果

# 读取图片
# img = cv2.imread("./test03.jpg", 1)[150:400, 50:300]
img = cv2.imread("C:\\Users\\Skey\\Pictures\\1\\timg2.jpg", 1)
height, width, channels = img.shape

# 灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 将图像分为8x8的多个小块,并统计小块每个像素的灰度值
# 划分灰度等级,例如0-255: 0-63, 64-127, ... 
# 找出每个小块中,每个等级的个数,找出最多的
# 用最多的的平均值替换原像素

dst_img = np.zeros((height, width, channels), np.uint8)
for i in range(0, height):
    for j in range(0, width):
        max_level_arr = []
        levelMap = {} # k: 级别, v: 原始像素值的列表
        for m in range(-4, 4):
            for n in range(-4, 4):
                # 处理越界
                if i + m >= height or i + m < 0:
                    m = -m
                if j + n >= width or j + n < 0:
                    n = -n
                
                # 划分等级 0-31, 32-63, ...
                level = gray_img[i + m, j + n] // 32
                if not level in levelMap.keys():
                    levelMap[level] = [img[i + m, j + n],]
                else:
                    levelMap[level].append(img[i + m, j + n])
                # 个数最多的级别
                if len(levelMap[level]) > len(max_level_arr):
                    max_level_arr = levelMap[level]
        # 取均值
        size = len(max_level_arr)
        b_sum, g_sum, r_sum = 0, 0, 0
        for b, g, r in max_level_arr:
            b_sum += b
            g_sum += g
            r_sum += r
        dst_img[i, j] = [b_sum // size, g_sum // size, r_sum // size ]
   

cv2.imshow("dst_img", dst_img)
if cv2.waitKey() == ord("q"):
    cv2.destroyAllWindows()

原图
油画图

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值