[opencv][python] 学习手册2:练习代码1

[opencv][python] 学习手册2:练习代码1

19_毛玻璃效果.py
20_浮雕效果.py
21_绘制形状.py
22_绘制文字.py
23_绘制文字_贴图.py
24_图片调亮.py
25_图片调亮_滑动条.py




19_毛玻璃效果.py

原理

  • 毛玻璃的效果和马赛克效果其实是非常相似的, 只不过毛玻璃效果是从附近的颜色块中,随机的去选择一个颜色值作为当前像素点的值!
  • 以4x4的块大小为例,遍历每个像素点的时候, 当前像素点的颜色值,随机从它附近4x4的区域内选择一个颜色值作为当前像素点的值!

在这里插入图片描述

代码

"""
需求:
对整幅图像进行毛玻璃处理

具体做法
毛玻璃效果是从附近的颜色块中,随机的去选择一个颜色值作为当前像素点的值!
需要偏移量变量,这个变量确定毛玻璃的毛化效果

算法
1. 计算当前像素点 row 的偏移量
2. 计算当前像素点 col 的偏移量
3. row,col 越界处理
4. 对当前像素进行赋值

流程
1. 读取图像,并获取信息
2. 创建一个与原图像大小通道相同的画布
3. 定义毛化偏移量 offset(随机点的取值范围)
4. 对图像进行毛化处理
5. 显示图像,等待按键
"""

import cv2 as cv
import numpy as np
import numpy.random as rnd

# 1. 读取图像,并获取信息
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_h = src.shape[0]
src_w = src.shape[1]

# 2. 创建一个与原图像大小通道相同的画布
# dst = np.zeros((src_h, src_w, 3), np.uint8)
dst = np.zeros(src.shape, src.dtype)

# 3. 定义毛化偏移量 offset(随机点的取值范围)
offset = 10

# 4. 对整幅图像进行毛化处理
for row in range(src_h):
    for col in range(src_w):
        # 1-2. 计算当前像素点 row, col 的偏移量
        row_offset = row + rnd.randint(0, offset)
        col_offset = col + rnd.randint(0, offset)
        # 3. row,col 越界处理,因为 offset 为正,所以只有右下越界
        if row_offset >= src_h:
            row_offset = row - 1
        if col_offset >= src_w:
            col_offset = col - 1
        # 4. 对当前像素进行赋值
        dst[row, col] = src[row_offset, col_offset]

# 5. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("dst", dst)

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述


20_浮雕效果.py

原理

  • 图像模糊是因为图像中物体的边缘轮廓不明显, 再进一步理解就是物体边缘灰度变化不强烈,层次感不强。
  • 那么反过来, 如果物体轮廓边缘灰度变化明显些, 层次感强些图像就清晰一些。
  • 灰度变化强度定义:在微积分中, 微分就是求函数的变化率,即导数(梯度). 梯度可以把它理解为颜色变化的强度, 更直白一点说梯度相当于是2个相邻像素之间的差值!

在这里插入图片描述

  • 第一行数据, 在X轴方向上,颜色值都为100,并没有看到任何的边缘
  • 在Y轴方向上, 可以看到100和50之间有明显的边缘,这个就是梯度
  • opencv中实现浮雕效果,只需套用公式: gray = gray0 - gray1 + 120
  • 相邻像素值之差可以体现边缘的突变或者称为梯度
  • 末尾加上120只是为了增加像素值的灰度
  • 运算的过程中,还需要注意计算结果有可能小于0或者大于255

代码

"""
需求:
对整幅图像进行浮雕效果处理(锐化处理)(对图像进行梯度处理)

具体做法
微分就是求函数的变化率,即导数(梯度).
其实梯度我们可以把它理解为颜色变化的强度,
更直白一点说梯度相当于是2个相邻像素之间的差值!

算法(水平方向)
1. 获取前一个像素的值
2. 获取当前像素的值
3. 计算梯度(微分,颜色突变):当前像素值 - 前一个像素值
4. 对梯度结果进行调节(补偿增量)
5. 将处理过的梯度结果赋值到当前像素位置


流程
1. 读取图像,并获取信息,转化成灰度图
2. 创建单通道同尺寸画布
3. 对原图进行梯度处理
4. 显示图像,等待按键
"""

import cv2 as cv
import numpy as np

# 1. 读取图像,并获取信息,转化成灰度图
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
src_h = src.shape[0]
src_w = src.shape[1]

# 2. 创建一个与原图像大小通道相同的画布
# dst = np.zeros((src_h, src_w, 3), np.uint8)
dst_1 = np.zeros(src_gray.shape, src_gray.dtype)
dst_2 = np.zeros(src_gray.shape, src_gray.dtype)

# 3. 对原图进行梯度处理
for row in range(src_h):
    for col in range(src_w):
        # 1. 获取前一个像素的值(复习:索引的正序与倒序,-1表示倒序第一个元素)
        color_pre = src_gray[row, col - 1]
        # 2. 获取当前像素的值
        color_cur = src_gray[row, col]
        # 3. 计算梯度(微分,颜色突变):int(当前像素值) - int(前一个像素值)
        gradient = int(color_cur) - int(color_pre)
        # 4. 对梯度结果进行调节(补偿增量)
        gradient = gradient + 120
        # gradient = np.uint8(gradient + 120)
        gradient = 255 if gradient > 255 else gradient
        gradient = 0 if gradient < 0 else gradient
        # 5. 将处理过的梯度结果赋值到当前像素位置z
        dst_1[row, col] = gradient

for col in range(src_w):
    for row in range(src_h):
        # 1. 获取前一个像素的值(复习:索引的正序与倒序,-1表示倒序第一个元素)
        color_pre = src_gray[row - 1, col]
        # 2. 获取当前像素的值
        color_cur = src_gray[row, col]
        # 3. 计算梯度(微分,颜色突变):int(当前像素值) - int(前一个像素值)
        gradient = int(color_cur) - int(color_pre)
        # 4. 对梯度结果进行调节(补偿增量)
        gradient = gradient + 120
        # gradient = np.uint8(gradient + 120)
        gradient = 255 if gradient > 255 else gradient
        gradient = 0 if gradient < 0 else gradient
        # 5. 将处理过的梯度结果赋值到当前像素位置z
        dst_2[row, col] = gradient

# 如何通过掩膜进行数据筛选?
rst2 = dst_1 + dst_2
# rst = int((int(dst_1) + int(dst_2)) / 2)
# mask = rst > 255
# rst[mask] = 255
rst = np.zeros(src_gray.shape, src_gray.dtype)

for row in range(src_h):
    for col in range(src_w):
        rst[row, col] = int(dst_1[row, col]) + int(dst_2[row, col])
        rst[row, col] = 255 if rst[row, col] > 255 else rst[row, col]
        rst[row, col] = 0 if rst[row, col] < 0 else rst[row, col]

# 5. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("dst1", dst_1)
cv.imshow("dst2", dst_2)
cv.imshow("rst", rst)
cv.imshow("rst2", rst2)

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述


21_绘制形状.py

代码

import cv2 as cv
import numpy as np

# 创建一个画布
dst = np.zeros((600, 800, 3), np.uint8)

# 绘制线段 1.图片 2.起始点 3.结束点 4.颜色 5.粗细
cv.line(dst, (95, 30), (480, 30), (0, 0, 255), 4)
# 绘制线段 1.图片 2.起始点 3.结束点 4.颜色 5.粗细 6.线条类型,抗锯齿
cv.line(dst, (95, 60), (480, 60), (0, 255, 255), 4, cv.LINE_AA)

# 绘制三角形 3 条线段
cv.line(dst, (70, 500), (150, 420), (255, 0, 0), 2, cv.LINE_AA)
cv.line(dst, (150, 420), (250, 500), (0, 255, 0), 2, cv.LINE_AA)
cv.line(dst, (250, 500), (70, 500), (0, 0, 255), 2, cv.LINE_AA)

# 绘制矩形  1.图像  2.左上角 3.右下角   4.颜色  5.粗细,若为负数则为填充 6.线条类型
cv.rectangle(dst, (72, 130), (200, 200), (255, 0, 0), 2, cv.LINE_AA)

cv.rectangle(dst, (72, 230), (200, 400), (255, 0, 0), -1, cv.LINE_AA)

# 绘制圆形 1.图像 2.圆心  3.半径  4.颜色  5.粗细 6.类型
cv.circle(dst, (380, 290), 100, (255, 0, 0), -1, cv.LINE_AA)

cv.imshow("dst", dst)
cv.waitKey(0)

运行结果
在这里插入图片描述


22_绘制文字.py

代码

"""
todo
用于物体识别
"""

import cv2 as cv

src = cv.imread("../img/room.jpg", cv.IMREAD_COLOR)

# 绘制矩形
cv.rectangle(src, (376, 160), (674, 234), (200, 200, 0), 2, cv.LINE_AA)

# 绘制文字: 1.图像 2.文本,不能有中文,3.起始位置 4.字体类型         5. 缩放  6.颜色 7.粗细  8.类型
cv.putText(src, 'www.baidu.com', (379, 151), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv.LINE_AA)

cv.circle(src, (379, 151), 2, (255, 255, 0), -1)

cv.imshow("src", src)

cv.waitKey(0)

运行结果
在这里插入图片描述


23_绘制文字_贴图.py

代码

"""
需求:todo
1. 将原图的特定区域框起来,并绘制文本
2. 将目标图像绘制到原图的指定位置
"""

import cv2 as cv

src = cv.imread("../img/room.jpg", cv.IMREAD_COLOR)

# 绘制矩形
cv.rectangle(src, (376, 160), (674, 234), (200, 200, 0), 2, cv.LINE_AA)

# 绘制文字: 1.图像 2.文本,不能有中文,3.起始位置 4.字体类型         5. 缩放  6.颜色 7.粗细  8.类型
cv.putText(src, 'this is a block', (379, 151), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2, cv.LINE_AA)

cv.circle(src, (379, 151), 2, (255, 255, 0), -1)

# 读取lena图片
lena = cv.imread("../img/lena.jpg")

# 图像下采样
lena = cv.pyrDown(lena)
height = lena.shape[0]
width = lena.shape[1]
# 贴图 获取到lena图像中的每一个像素
for row in range(height):
    for col in range(width):
        # 获取lena图中的颜色值
        color = lena[row, col]

        # 将颜色值填充到原图中的某个位置
        offsetRow = 150
        offsetCol = 100

        src[offsetRow + row, offsetCol + col] = color

cv.imshow("lena", lena)
cv.imshow("src", src)

cv.waitKey(0)

运行结果
在这里插入图片描述


24_图片调亮.py

代码

"""
需求:
1. 读取图像,获取信息
2. 定义增量变量
3. 遍历每一个像素点,将像素值调高
4. 显示图像,等待按键
"""

import cv2 as cv
import numpy as np

# # 通过 图像 * 数值 进行图像颜色调节
# # 创建一个黑色的图像
# dst = np.ones((600, 400, 1), np.uint8)
# cv.imshow("dst1", dst)
#
# dst *= 100
# cv.imshow("dst2", dst)
#
# dst *= 2
# cv.imshow("dst3", dst)
#
# key = cv.waitKey(0)
# print("key = ", key)


# 1. 读取图像,获取信息
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_h = src.shape[0]
src_w = src.shape[1]

# 2. 定义增量变量
offset = 50

# 3. 遍历每一个像素点,将像素值调高
dst = np.zeros(src.shape, src.dtype)

for row in range(src_h):
    for col in range(src_w):
        # B, G, R = src[row, col][0], src[row, col][1], src[row, col][2]
        color = src[row, col]
        # 修改每个通道像素值
        B = int(color[0]) + offset
        G = int(color[1]) + offset
        R = int(color[2]) + offset
        # 溢出处理
        B = 255 if B > 255 else B
        G = 255 if G > 255 else G
        R = 255 if R > 255 else R
        # 修改原图像
        dst[row, col] = (B, G, R)

# 4. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("dst", dst)

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述


25_图片调亮_滑动条.py

代码

"""
需求:
1. 读取图像,获取信息
2. 定义增量变量
3. 遍历每一个像素点,将像素值调高
4. 显示图像,等待按键


将图像调节代码封装成一个函数,change_brightness
在通过 cv 的 createTrackbar api 调用这个函数

疑问,如何调用多参数回调函数

"""

import cv2 as cv
import numpy as np


# # 通过 图像 * 数值 进行图像颜色调节
# # 创建一个黑色的图像
# dst = np.ones((600, 400, 1), np.uint8)
# cv.imshow("dst1", dst)
#
# dst *= 100
# cv.imshow("dst2", dst)
#
# dst *= 2
# cv.imshow("dst3", dst)
#
# key = cv.waitKey(0)
# print("key = ", key)

# todo. 多参数回调函数如何传参?
# def change_brightness(img_src, img_dst, offset):
#     height = img_src.shape[0]
#     width = img_src.shape[1]
#     for row in range(height):
#         for col in range(width):
#             # B, G, R = src[row, col][0], src[row, col][1], src[row, col][2]
#             color = src[row, col]
#             # 修改每个通道像素值
#             B = int(color[0]) + offset
#             G = int(color[1]) + offset
#             R = int(color[2]) + offset
#             # 溢出处理
#             B = 255 if B > 255 else B
#             G = 255 if G > 255 else G
#             R = 255 if R > 255 else R
#             # 修改原图像
#             img_dst[row, col] = (B, G, R)
#     # 每一次调节显示图像
#     cv.imshow("dst", img_dst)

def change_brightness(offset):
    global src, dst
    for row in range(src_h):
        for col in range(src_w):
            # B, G, R = src[row, col][0], src[row, col][1], src[row, col][2]
            color = src[row, col]
            # 修改每个通道像素值
            B = int(color[0]) + offset
            G = int(color[1]) + offset
            R = int(color[2]) + offset
            # 溢出处理
            B = 255 if B > 255 else B
            G = 255 if G > 255 else G
            R = 255 if R > 255 else R
            # 修改原图像
            dst[row, col] = (B, G, R)
    # 每一次调节显示图像
    cv.imshow("dst", dst)


def on_track_bar(img, offset):
    print("img = ", img)
    print("offset = ", offset)


# 1. 读取图像,获取信息
filename = r"../img/lena.jpg"
src = cv.imread(filename, cv.IMREAD_COLOR)
src_h = src.shape[0]
src_w = src.shape[1]

# 3. 创建一个与原图像相同属性的画布
dst = np.zeros(src.shape, src.dtype)

# 4. 显示图像,等待按键
cv.imshow("src", src)
cv.imshow("dst", src)

# 5. 创建滑动条,并绑定 change_brightness 函数
# cv.createTrackbar("brightness", "dst", -100, 100, on_track_bar)
cv.createTrackbar("brightness", "dst", 0, 100, change_brightness)

# on_track_bar(30)

key = cv.waitKey(0)
print("key = ", key)

运行结果
在这里插入图片描述

for 循环效率很低,可以尝试采用数组广播方式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值