AI智能
改变未来

快速学完OpenCV+python计算机视觉图像处理(四)

以下是快速学完OpenCV+python计算机视觉图像处理的个人总结。

任何知识或者学科都不可能快速学会,一口吃不成大胖子,想要学会,只能一点一点积累。

不积跬步无以至千里,不敲千遍无可能懂理。

想要学会,不能光看,须知熟才能生巧,一定要多敲!一定要多敲!一定要多敲!

视频链接请点击这里

代码连接请点击这里 ,提取码: iukw

看完视频一定要手动敲,不然最后只是眼睛会了,脑子和手却不会。

以下是Windows、Linux、Mac深度学习环境搭建详细教程:

1、windows搭建深度学习环境详细教程

2、Linux系统搭建深度学习环境详细教程

3、Mac系统搭建深度学习环境详细教程

4 图像基本特效

4-1 图像特效介绍

图像特效分为以下几个,分别是:

  1. 灰度处理
  2. 底板效果
  3. 马赛克
  4. 毛玻璃效果
  5. 图像融合
  6. 图片蓝色
  7. 边缘检测
  8. 浮雕效果

4-2 图像灰度处理1

灰度处理常用方法:

  • 方法1,直接使用imread里面的参数,代码如下:
import cv2src = 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 cv2src = 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 cv2import numpy as npimg = cv2.imread('16.jpg', 1)cv2.imshow('src', img)imgInfo = img.shapeheight = 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)) / 3dst[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 cv2import numpy as npimg = cv2.imread('15.jpg', 1)cv2.imshow('src', img)imgInfo = img.shapeheight = 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.114dst[i, j] = np.uint8(gray)cv2.imshow('dst', dst)cv2.waitKey(0)

运行结果如下:

  • 方法5,使用明度算法Lightness将彩色图像转换为灰度图像,代码如下:
import cv2import numpy as npimg = cv2.imread('14.jpg', 1)cv2.imshow('src', img)imgInfo = img.shapeheight = 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)) / 2dst[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.114Gray_Lightness = (max(R, G, B) + min(R, G, B)) / 2Gray_Average = (R + G + B) / 3

4-4 算法优化

代码如下:

import cv2import numpy as npimport datetimeimg = cv2.imread('13.jpg')imgInfo = img.shapeheight = 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)>>2gray = (r + (b << 1) + b) >> 2dst[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.261156after optimize: 0:00:00.203124

从运行结果可以看出,优化后的时间要比优化之前快那么一点点。

4-5 颜色反转

  1. 灰度图像反转

代码如下:

import cv2import numpy as npimg = cv2.imread('12.jpg', 1)imgInfo = img.shapeheight = 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 - grayPixelcv2.imshow('dst', dst)cv2.waitKey(0)

运行结果如下:

  1. 彩色图像反转

代码如下:

import cv2import numpy as npimg = cv2.imread('12.jpg', 1)# cv2.imshow('img', img)imgInfo = img.shapeheight = 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 cv2img = cv2.imread('17.jpg', 1)cv2.imshow('img', img)imgInfo = img.shapeprint(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 cv2import numpy as npimg = cv2.imread('1.jpg', 1)cv2.imshow('img', img)imgInfo = img.shapeheight = imgInfo[0]width = imgInfo[1]dst = np.zeros((height, width, 3), np.uint8)mn = 6for m in range(0, height - mn):  # 为了防止溢出需要减去6for 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 cv2import numpy as npimg1 = cv2.imread('1.jpg')img2 = cv2.imread('2.jpg')img1Info = img1.shapeheight = 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]# dstdst = 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.Cannyimg = 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 cv2import numpy as npimport mathimg = cv2.imread('5.jpg', 1)imgInfo = img.shapeheight = 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>thgray = 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 cv2import numpy as npimg = cv2.imread('7.jpg', 1)cv2.imshow('img', img)imgInfo = img.shapeheight = imgInfo[0]width = imgInfo[1]gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# newP = grayP0 - grayP1 + 150dst = 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 + 150if newP > 255:newP = 255if newP < 0:newP = 0dst[i, j] = newPcv2.imshow('dst', dst)cv2.waitKey(0)

运行结果如下:

4-12 颜色映射

代码如下:

import cv2import numpy as npimg = cv2.imread('8.jpg', 1)cv2.imshow('src', img)imgInfo = img.shapeheight = 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 = 1.1 * bg = 1.1 * gr = 6.6 * rif b > 255:b = 255if g > 255:g = 255if r > 255:r = 255dst[i, j] = (b, g, r)cv2.imshow('dst', dst)cv2.waitKey(0)

运行结果如下:

哈哈哈,给我们的小姐姐染了个红发

4-13 油画特效

优化特效步骤如下:

  1. 彩色图片转换为灰度图片;
  2. 将图片分割为若干个小方块,统计这些小方块中每一个像素的灰度值(eg:77或者1010的小方块);
  3. 将0~255划分为几个等级,将第二步的结果映射过来分为不同的等级段中,
  4. 找到每个方块中灰度等级最多的像素,并且求取像素的均值。
  5. 将统计出来的平均值替换原来的像素值,最终来实现优化效果
    代码如下:
import cv2import numpy as npimg = cv2.imread('6.jpg', 1)cv2.imshow('img', img)imgInfo = img.shapeheight = imgInfo[0]width = imgInfo[1]gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)dst = np.zeros((height, width, 3), np.uint8)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):for n in range(-4, 4):p1 = int(gray[i + m, j + n] / 32)array1[p1] = array1[p1] + 1currentMax = array1[0]l = 0for 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):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)

运行结果如下:

4-14 线段绘制

绘制线段要用到

cv2.line()

函数,函数原型为

img=cv.line(img, pt1, pt2, color[, thickness[, lineType[, shift]]])

,主要参数如下:

  • img:源图像
  • pt1:直线起点
  • pt2:直线终点
  • color:需要传入的颜色
  • thickness:线条的粗细,默认值是1
  • linetype:线条的类型,8 连接,抗锯齿等。默认情况是 8 连接。cv2.LINE_AA 为抗锯齿,这样看起来会非常平滑。

代码如下:

import cv2img = cv2.imread('9.jpg', 1)cv2.imshow('img', img)# 绘制线段 1.dst;2.begin;3.end;4.color;5.width;6.typecv2.line(img, (260, 150), (350, 180), (0, 255, 0), 18, cv2.LINE_AA)# 绘制三角形cv2.line(img, (300, 450), (200, 380), (0, 255, 255), 38, cv2.LINE_AA)cv2.line(img, (200, 380), (400, 380), (0, 255, 255), 38, cv2.LINE_AA)cv2.line(img, (400, 380), (300, 450), (0, 255, 255), 38, cv2.LINE_AA)cv2.imshow('img', img)cv2.waitKey(0)

运行结果如下:

4-15 矩形圆形任意多边形绘制

绘制圆形用到的是

cv2.circle()

,绘制椭圆用到的是

cv2.ellipse()

,绘制长方形用到的是

cv2.rectangle()

cv2.polylines()

可以用来画很多条线。只把想画的线放在一 个列中将列传给函数就可以了。每条线会独立绘制。会比用

cv2.line()

一条一条的绘制快一些。

运行代码如下:

import cv2import numpy as npimg = cv2.imread('00.jpg', 1)# rectangle是来画矩形框的,其中:1.src;2.左上角;3.右下角;4.color;5.如果为-1,则fill,如果>0则表示line widthcv2.rectangle(img, (180, 300), (300, 400), (0, 255, 255), -1)# circle是用来画圆的,其中:1.src;2.center;3.r;4.color,5.同rectanglecv2.circle(img, (240, 160), 80, (0, 255, 0), 2)# ellipse是用来画椭圆的,其中:1.src;2.中心坐标;3.长、短轴长度;4.椭圆旋转角度;5.6.椭圆弧起始和终止角度;7.color;8.线宽或填充cv2.ellipse(img, (410, 130), (100, 70), 80, 0, 360, (0, 0, 255), 3)# polylines画多边形points = np.array([[358, 54], [385, 120], [357, 163], [401, 165], [433, 237],[440, 165], [485, 166], [442, 119], [442, 28], [411, 84]],np.int32)  # 这个数组必须为int32print(points.shape)  # (10, 2)# 这里reshape的第一个参数为-1,表明这一维度的长度是根据后面的维度计算出来的points = points.reshape((-1, 1, 2))print(points.shape)  # (10, 1, 2)# 1.src;2.point;3.True表示闭合的线,False不闭合;4.color;5.只有线宽,-1报错不会填充cv2.polylines(img, [points], True, (0, 255, 255), 3)cv2.imshow('img', img)cv2.waitKey()

运行结果如下:

4-16 文字图片绘制

代码如下:

import cv2img = cv2.imread('00.jpg', 1)font = cv2.FONT_HERSHEY_SIMPLEX  # 文字的字体类型,FONT_HERSHEY_SIMPLEX表示正常大小无衬线字体# putText显示文本,其中:1.src;2.text;3.org;4.font;5.text size;6.color;7.line width;8.stylecv2.putText(img, 'I Love You', (300, 350), font, 1, (255, 0, 0), 2, cv2.LINE_AA)cv2.imshow('img', img)cv2.waitKey(0)

运行结果如下:

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 快速学完OpenCV+python计算机视觉图像处理(四)