快速学完OpenCV+python计算机视觉图像处理
Posted 满目星辰wwq
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速学完OpenCV+python计算机视觉图像处理相关的知识,希望对你有一定的参考价值。
4 图像基本特效
4-1 图像特效介绍
图像特效分为以下几个,分别是:
- 灰度处理
- 底板效果
- 马赛克
- 毛玻璃效果
- 图像融合
- 图片蓝色
- 边缘检测
- 浮雕效果
4-2 图像灰度处理1
灰度处理常用方法:
- 方法1,直接使用imread里面的参数,代码如下:
import cv2
src = cv2.imread('17.jpg', 1)
gray1 = cv2.imread('17.jpg', 0)
gray2 = cv2.imread('17.jpg', cv2.IMREAD_GRAYSCALE)
print(src.shape)
print(gray1.shape)
print(gray2.shape)
cv2.imshow('src', src)
cv2.imshow('gray1', gray1)
cv2.imshow('gray2', gray2)
cv2.waitKey(0)
运行结果如下:
(308, 204, 3)
(308, 204)
(308, 204)
- 方法2,使用OpenCV里面的cvtColor将RGB图像转换为灰度图像,代码如下:
import cv2
src = cv2.imread('17.jpg', 1)
cv2.imshow('src', src)
gray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)
cv2.waitKey(0)
运行结果如下:
4-3 图像灰度处理2
- 方法3,将RGB3个维度的数相加除以3,这就是均值算法Average,代码如下:
import cv2
import numpy as np
img = cv2.imread('16.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]
gray = (int(b) + int(g) + int(r)) / 3
dst[i, j] = np.uint8(gray)
cv2.imshow('dst', dst)
cv2.waitKey(0)
运行结果如下:
- 方法4,使用特定公式gray = r0.299+g0.587+b*0.114将RGB图像转换为灰度图像,这公式叫做亮度算法Luminosity,除了亮度算法和均值算法求灰度图像,还有一种明度算法Lightness也是可以将彩色图像转换为灰度图像的。亮度算法代码如下:
import cv2
import numpy as np
img = cv2.imread('15.jpg', 1)
cv2.imshow('src', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros(imgInfo, 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)
运行结果如下:
- 方法5,使用明度算法Lightness将彩色图像转换为灰度图像,代码如下:
import cv2
import numpy as np
img = cv2.imread('14.jpg', 1)
cv2.imshow('src', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros(imgInfo, 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 = (max(r, g, b) + min(r, g, b)) / 2
dst[i, j] = np.uint8(gray)
cv2.imshow('dst', dst)
cv2.waitKey(0)
运行结果如下:
以下将Luminosity(亮度)、Lightness(明度)、Average(均值)三个算法公式列在下面:
Gray_Luminosity = R*0.299 + G*0.587 + B*0.114
Gray_Lightness = (max(R, G, B) + min(R, G, B)) / 2
Gray_Average = (R + G + B) / 3
4-4 算法优化
代码如下:
import cv2
import numpy as np
import datetime
img = cv2.imread('13.jpg')
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros(imgInfo, np.uint8)
oldtime = datetime.datetime.now()
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)
# r*0.299+g*0.587+b*0.114=((r*0.299+g*0.587+b*0.114)*2^2)*2^-2
# =(r*1.196+g*2.348+b*0.456)*2^-2约等于(r*1+g*2+b*1)*2^-2
# 进行二进制位移转换=(r+(b<<1)+b)>>2
gray = (r + (b << 1) + b) >> 2
dst[i, j] = np.uint8(gray)
newtime = datetime.datetime.now()
print('after optimize', newtime - oldtime)
cv2.imshow('dst', dst)
cv2.waitKey(0)
运行结果如下:
before optimize: 0:00:00.261156
after optimize: 0:00:00.203124
从运行结果可以看出,优化后的时间要比优化之前快那么一点点。
4-5 颜色反转
- 灰度图像反转
代码如下:
import cv2
import numpy as np
img = cv2.imread('12.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('gray', gray)
dst = np.zeros(gray.shape, np.uint8)
dst2 = 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)
运行结果如下:
- 彩色图像反转
代码如下:
import cv2
import numpy as np
img = cv2.imread('12.jpg', 1)
# cv2.imshow('img', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros(img.shape, np.uint8)
dst2 = 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]
b2 = int(b)
g2 = int(g)
r2 = int(r)
dst[i, j] = (255 - b, 255 - g, 255 - r)
dst2[i, j] = (255 - b2, 255 - g2, 255 - r2)
cv2.imshow('dst', dst)
cv2.imshow('dst2', dst2)
cv2.waitKey(0)
运行结果如下:
4-6 马赛克
源代码如下:
import cv2
img = cv2.imread('17.jpg', 1)
cv2.imshow('img', img)
imgInfo = img.shape
print(imgInfo)
height = imgInfo[0]
width = imgInfo[1]
for m in range(140, 180): # 高,选取图像(100,140)->(150,180)这片区域
for n in range(100, 150): # 宽
if m % 10 == 0 and n % 10 == 0: # 针对这片区域的10*10小方格进行筛选
for i in range(0, 10):
for j in range(0, 10):
b, g, r = img[m, n] # 选择在m->n这个区域的原图像
img[i + m, j + n] = b, g, r # 将m->n这个区域的原图像每一块10*10区域和第一个位置的相同
cv2.imshow('dst', img)
cv2.waitKey(0)
运行结果如下:
4-7 毛玻璃
代码如下:
import cv2
import numpy as np
img = cv2.imread('1.jpg', 1)
cv2.imshow('img', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height, width, 3), np.uint8)
mn = 6
for m in range(0, height - mn): # 为了防止溢出需要减去6
for n in range(0, width - mn):
index = int(np.random.random() * 6)
dst[m, n] = img[m + index, n + index]
cv2.imshow('dst', dst)
cv2.waitKey(0)
运行结果如下:
4-8 图片融合
代码如下:
# dst = src1 * α + src2 * (1 - α)
import cv2
import numpy as np
img1 = cv2.imread('1.jpg')
img2 = cv2.imread('2.jpg')
img1Info = img1.shape
height = img1Info[0]
width = img1Info[1]
# ROI # 这个要不要无所谓
# roiH = int(height * 0.5)
# roiW = int(width * 0.5)
# img1ROI = img1[0:roiH, 0:roiW]
# img2ROI = img2[0:roiH, 0:roiW]
# dst
dst = np.zeros((height, width, 3), np.uint8)
# dst2 = np.zeros((roiH, roiW, 3), np.uint8)
dst = cv2.addWeighted(img1, 0.4, img2, 0.6, 0)
# dst2 = cv2.addWeighted(img1ROI, 0.5, img1ROI, 0.5, 0)
cv2.imshow('dst', dst)
# cv2.imshow('dst2', dst2)
cv2.waitKey(0)
运行结果如下:
4-9 边缘检测1
这里讲的边缘检测算子是Canny算子,Canny 的目标是找到一个最优的边缘检测算法,其原型为:
edge = cv2.Canny(image, threshold1, threshold2[, edges[, apertureSize[, L2gradient ]]])
必要参数:
- 第一个参数是需要处理的原图像,该图像必须为单通道的灰度图;
- 第二个参数是低阈值,小于这个值时,像素值排除 ;
- 第三个参数是高阈值,大于这个值时,像素值保留为边缘像素;
- 注:当像素值位于两个阈值中间时,该像素仅仅在连接到一个高于高阈值的像素时被保留。
代码如下:
import cv2
# 边缘检测分为3个步骤:1.BGR2Gray;2.GaussianBlur;3.Canny
img = cv2.imread('3.jpg')
cv2.imshow('img', img)
# 1.将彩色图像转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2.将灰度图像通过高斯滤波进行平滑处理
gauss = cv2.GaussianBlur(gray, (5, 5), 0) # 核大小必须是奇数,最后一个参数0代表高斯核标准偏差
# 3.利用Canny算子检测出边缘
dst = cv2.Canny(gauss, 100, 110) # 第二个和第三个是最小最大阈值,一般都是经验值
cv2.imshow('canny', dst)
cv2.waitKey(0)
运行结果如下:
4-10 边缘检测2
这里使用边缘检测算子是Soble算子,Sobel 算子是一个主要用作边缘检测的离散微分算子 (discrete differentiation operator)。Sobel算子结合了高斯平滑和微分求导,用来计算图像灰度函数的近似梯度。
代码如下:
import cv2
import numpy as np
import math
img = cv2.imread('5.jpg', 1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src', img)
# sobel:1.算子模板;2.图片卷积;3.阈值判决
# [1 2 1 [ 1 0 -1
# 0 0 0 2 0 -2
# -1 -2 -1 ] 1 0 -1 ]
# [1 2 3 4] [a b c d] a*1+b*2+c*3+d*4 = dst
# sqrt(a*a+b*b) = f>th
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
dst = np.zeros((height, width, 1), np.uint8)
for i in range(0, height - 2): # 因为卷积核实3*3,这里需要减去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 # 垂直变化:将灰度图像与3*3内核进行卷积
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] # 水平变化:将灰度图像与3*3内核进行卷积
grad = math.sqrt(gx * gx + gy * gy) # 这里用G=sqrt(Gx^2+Gy^2)来求近似梯度
grad = math.fabs(gx) + math.fabs(gy) # 也可以用G=|Gx|+|Gy|求近似梯度
if grad > 100: # 大于100的设置为边缘,值越小检测的边缘越浓密
dst[i, j] = 255 # 255为白色
else: # 小于100的不是边缘
dst[i, j] = 0 # 0为黑色
cv2.imshow('dst', dst)
cv2.waitKey(0)
运行结果如下:
4-11 浮雕效果
运行代码如下:
import cv2
import numpy as np
img = cv2.imread('7.jpg', 1)
cv2.imshow('img', img)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# newP = grayP0 - grayP1 + 150
dst = np.zeros((height, width, 1)快速学完OpenCV+python计算机视觉图像处理