一、灰度处理
方法一:imread方法
彩色图的颜色通道为3,即RGB;而灰度图只有一个颜色通道。
import cv2
img0 = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',0)
img1 = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
print(img0.shape)
print(img1.shape)cv2.imshow('src',img0)#灰度图片
cv2.waitKey(0)
结果如下:
方法二:cvtColor方法
颜色空间转换
cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
参数一:原始待转换数据图片
参数二:颜色转换方式,BGR转GRAY
import cv2
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
dst = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#颜色空间转换
cv2.imshow('dst',dst)#灰度图片
cv2.waitKey(0)
效果图如下:
方法三:灰度图像==彩色图像(R+G+B)/3
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#灰度图像的GBR都相等,为彩色照片的均值
dst1 = 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))/3dst1[i,j] = np.uint8(gray)cv2.imshow('dst1',dst1)#灰度图片
cv2.waitKey(0)
效果图如下:
方法四:灰度图像==彩色图像( R * 0.299+G * 0.587 + B * 0.114)
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#灰度图像的GBR都相等,为彩色照片的均值
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]gray = (int(b)*0.114+int(g)*0.587+int(r)*0.299)dst2[i,j] = np.uint8(gray)cv2.imshow('dst2',dst2)#灰度图片
cv2.waitKey(0)
效果图如下:
二、算法优化
1、定点计算比浮点计算快
2、加减运算比乘除运算快
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#灰度图像的GBR都相等,为彩色照片的均值
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]#gray = (int(b)*0.114+int(g)*0.587+int(r)*0.299)#gray = (int(b)+int(g)*2+int(r))/4#乘4除4gray = (r+(g<<1)+b)>>2#g乘2左移一位;除以4右移两位dst2[i,j] = np.uint8(gray)cv2.imshow('dst2',dst2)#灰度图片
cv2.waitKey(0)
效果图如下:
三、颜色反转
灰度图像颜色反转:0-255,即:255-当前值
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',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)#这里只传入一个颜色通道(height,width,1)当成灰度图处理
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)
效果图如下:
彩色图像的颜色反转:RGB每个颜色通道的像素值都需要被255减去
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)#(height,width,1)一个像素值有三个颜色通道组成
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;将马赛克方块中的一个像素值去替代整个马赛克方块中的所有像素点
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
for i in range(100,300):for j in range(100,200):if i%10 ==0 and j%10==0 :#定义一个10*10的马赛克方块,用马赛克方块中的一个去代替整个马赛克的像素值for m in range(0,10):for n in range(0,10):(b,g,r) = img[i,j]img[m+i,n+j] = (b,g,r)cv2.imshow('dst',img)
cv2.waitKey(0)
效果图如下:
五、图片的毛玻璃效果
毛玻璃效果:定义毛玻璃方块,例如为10*10;随机生成一个像素点去依次代替毛玻璃方块中的所有像素点
import cv2
import numpy as np
import random
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
mm = 8
for m in range(0,height-mm):for n in range(0,width-mm):index = int(random.random()*8)#随机生成0-8这些数,去代替其他的像数值(b,g,r) = img[m+index,n+index]dst[m,n] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果图如下:
六、图片的融合效果
采用每个图片乘以一个比例系数然后相加进行融合的方式;两张融合的图片的大小必须一致
cv2.addWeighted(img0ROI,0.5,img1ROI,0.5,0)
参数一:图片1
参数二:图片1对应的权值
参数三:图片2
参数四:图片2对应的权值
参数五:偏移量,一般默认设置为0
import cv2
import numpy as np
img0 = cv2.imread('E:\Jupyter_workspace\study\data/water.png',1)#这两张图片必须大于第一张图片的一半
img1 = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img0.shape
height = imgInfo[0]
width = imgInfo[1]
#ROI选取一块区域进行照片融合;且选取的大小必须比原图像要小
roiH = int(height/2)
roiW = int(width/2)
img0ROI = img0[0:roiH,0:roiW]
img1ROI = img1[0:roiH,0:roiW]
#dst 定义目标图片
dst = np.zeros((roiH,roiW,3),np.uint8)
dst = cv2.addWeighted(img0ROI,0.5,img1ROI,0.5,0)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果图如下:
七、边缘检测
边缘检测的实质就是图像的卷积运算
调用Canny方法api实现边缘检测
canny边缘检测步骤:
1,对图像先进行灰度处理
2,高斯滤波,除去图像中一下噪声的干扰
3,调用canny方法实现边缘检测
cv2.Canny(img,50,50)
参数一:传入的图片数据
参数二:如果图片进行卷积运算之后大于该值,则认定为边缘
import cv2
import numpy as np
import randomimg = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('img',img)gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#1,转换灰度图像
imgG = cv2.GaussianBlur(gray,(3,3),0)#2,高斯滤波
dst = cv2.Canny(img,50,50)#3,调用Canny算法
cv2.imshow('dsr',dst)
cv2.waitKey(0)
效果图如下:
使用sobel算子用源码方式实现边缘检测
soble算子的算法原理:
1,算子的模板
水平方向模板:
1 2 1
0 0 0
-1 -2 -1
竖直方向模板:
1 0 -1
2 0 -2
1 0 -1
2,图片卷积
矩阵卷积是矩阵对应的元素相乘然后再求和,并不是矩阵相乘!!!
例如:[1,2,3,4]为原像素,计算模板为[a,b,c,d],卷积之后结果为:dst = a1+b2+c3+d4
这个dst就是所谓的梯度,也分为水平方向gx和竖直方向gy
grad = sqrt(gxgx+gygy)
3,阈值判决
grad和阈值进行判断
import cv2
import numpy as np
import random
import math
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',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)#因为处理的是灰度图片所以参数为1
for i in range(0,height-2):#因为矩阵是3*3的,矩阵右下角坐标为2,所以要-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]*1gx = 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:dst[i,j] = 255else:dst[i,j] = 0
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果图如下:
八、图片的浮雕效果
前一个像数值-后一个像数值+一个恒定的常量
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',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])#因为宽度+1了,所以j需要减一,否则会造成数组越界newP = grayP0-grayP1+150if newP>255:newP=255if newP<0:newP=0dst[i,j] = newP
cv2.imshow('dst',dst)
cv2.waitKey(0)
九、颜色的映射变化改变图片的颜色风格
偏蓝风格:b1.5+g1.3
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
cv2.imshow('img',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.5g = g*1.3if b>255:b=255if g>255:g=255dst[i,j] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
效果图如下:
十、图片的油画效果
实现步骤:
1、实现彩色到灰色照片的转换
2、将图片分割为若干个小方块,统计这些小方块中的每个像素值
3、将0-255的灰度值划分为若干个等级,再把每个像素值映射到这些等级中
4、找到每个等级中含有像素最多的等级,并且求取这些像素的均值;从而实现每个小方块中像素个数的统计
5、用统计出来的平均值来替代原来的像素值,最终实现油画效果
import cv2
import numpy as np
img = cv2.imread('E:\Jupyter_workspace\study\data/cat.png',1)
cv2.imshow('img',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)#定义目标图片
for i in range(4,height-4):#因为下面的循环是定义的小方块大小为8*8for j in range(4,width-4):array1 = np.zeros(8,np.uint8)#定义的灰度等级为8个,这里定义一个数组装载这8个等级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)
效果图如下: