目录
一、灰度处理 二、颜色反转 三、马赛克 四、毛玻璃 五、图片融合 六、边缘检测与浮雕效果
七、颜色映射 八、油画效果
一、灰度处理
import cv2
img0 = cv2. imread( 'image0.jpg' , 0 )
img1 = cv2. imread( 'image0.jpg' , 1 )
print ( img0. shape)
print ( img1. shape)
cv2. imshow( 'src' , img0)
cv2. waitKey( 0 )
使用openCV的cvtColor方法实现 :cvtColor实现颜色空间的转换
import cv2
img = cv2. imread( 'image0.jpg' , 1 )
dst = cv2. cvtColor( img, cv2. COLOR_BGR2GRAY)
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
利用R=G=B的方式实现 :使用(R+G+B)/ 3 赋值给像素点
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 1 )
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 )
使用心理学公式 :r * 0.299 + g * 0.587 + b * 0.114
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 1 )
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 = 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 )
算法优化 :浮点数据转换成定点数据;乘除转换成位移计算
这里的系数是按乘以4计算了,如果希望精度更快,可以乘100,1000。。。。。
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 1 )
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 = int ( b)
g = int ( g)
r = int ( r)
gray = ( r + ( g << 1 ) + b) >> 2
dst[ i, j] = np. uint8( gray)
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
二、颜色反转
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 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) :
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( 'image0.jpg' , 1 )
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]
dst[ i, j] = ( 255 - b, 255 - g, 255 - r)
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
三、马赛克
图片实现马赛克的原理 :将一片区局域中的所有的像素保持一致
例如:我们想给一个10 * 10的区域打上马赛克 那么我们取到10*10中左上角点的像素值,替换掉10 * 10的100个像素点 这样就实现了马赛克效果
import cv2
img = cv2. imread( 'image0.jpg' , 1 )
imgInfo = img. shape
height = imgInfo[ 0 ]
width = imgInfo[ 1 ]
for m in range ( 100 , 300 ) :
for n in range ( 100 , 200 ) :
if m % 10 == 0 and n % 10 == 0 :
for i in range ( 0 , 10 ) :
for j in range ( 0 , 10 ) :
( b, g, r) = img[ m, n]
img[ i + m, j + n] = ( b, g, r)
cv2. imshow( 'dst' , img)
cv2. waitKey( 0 )
四、毛玻璃
毛玻璃的实现原理 :
马赛克效果我们使用的是左上角的像素点来替换掉其他像素点 而毛玻璃是使用随机的像素点来替换掉当前的像素点
import cv2
import numpy as np
import random
img = cv2. imread( 'image0.jpg' , 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 )
( b, g, r) = img[ m + index, n + index]
dst[ m, n] = ( b, g, r)
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
五、图片融合
2张图片融合的计算公式 :dst = src1a+src2 (1-a),其中a指的是alpha系数
import cv2
img0 = cv2. imread( 'image0.jpg' , 1 )
img1 = cv2. imread( 'image1.jpg' , 1 )
imgInfo = img0. shape
height = imgInfo[ 0 ]
width = imgInfo[ 1 ]
roiH = int ( height / 2 )
roiW = int ( width / 2 )
img0ROI = img0[ 0 : roiH, 0 : roiW]
img1ROI = img1[ 0 : roiH, 0 : roiW]
dst = cv2. addWeighted( img0ROI, 0.5 , img1ROI, 0.5 , 0 )
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
六、边缘检测与浮雕效果
1 - 边缘检测
什么是边缘检测 :边缘检测的效果有点类似素描,边缘检测的实质是图像的卷积计算openCV的API方式实现边缘检测的步骤 :
import cv2
img = cv2. imread( 'image0.jpg' , 1 )
imgInfo = img. shape
height = imgInfo[ 0 ]
width = imgInfo[ 1 ]
cv2. imshow( 'src' , img)
gray = cv2. cvtColor( img, cv2. COLOR_BGR2GRAY)
imgG = cv2. GaussianBlur( gray, ( 3 , 3 ) , 0 )
dst = cv2. Canny( img, 50 , 50 )
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
源码形式实现边缘检测 :sobel算法实现,这里会涉及到如下几个概念sobel算法的算子模板 :水平方向、垂直方向
水平方向 垂直方向
[ 1 2 1 [ 1 0 - 1
0 0 0 2 0 - 2
- 1 - 2 - 1 ] 1 0 - 1 ]
图片卷积 :假设1张图片中的4个像素点为[1 2 3 4],当前的模板是[a b c d],那么卷积的结果:a1+b 2+c3+d 4 = dst
a:竖直方向上的梯度 -> 水平方向上的算子与图片卷积的结果 b:水平方向上的梯度 -> 垂直方向上的算子与图片卷积的结果 f:阀值,f = sqrt(a * a + b * b) th:判决门限 阀值判决 :f > th 是边缘,否则是非边缘
import cv2
import numpy as np
import math
img = cv2. imread( 'image0.jpg' , 1 )
imgInfo = img. shape
height = imgInfo[ 0 ]
width = imgInfo[ 1 ]
cv2. imshow( 'src' , img)
gray = cv2. cvtColor( img, cv2. COLOR_BGR2GRAY)
dst = np. zeros( ( height, width, 1 ) , np. uint8)
for i in range ( 0 , height - 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
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 ]
grad = math. sqrt( gx * gx + gy * gy)
if grad > 50 :
dst[ i, j] = 255
else :
dst[ i, j] = 0
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
2 - 浮雕效果
浮雕效果计算公式 :每一个新的像素值等于相邻像素的像素值之差加上一个恒定值(比如150)
newP = gray0 - gray1 + 150 这里加上150是为了增强图片的浮雕灰度等级 相邻像素相减是为了突出灰度的突片及边缘特征
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 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 ] )
newP = grayP0 - grayP1 + 150
if newP > 255 :
newP = 255
if newP < 0 :
newP = 0
dst[ i, j] = newP
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
七、颜色映射
颜色映射最简单的实现方式 :
做一个很大的查找表,根据原始图像的rgb值根据查找表查找一组新的rgb,用新的rgb代替原来像素值 也可以用一些简单的公式完成颜色映射,利用公式的方法可能无法表示一些更为复杂的效果 案例:蓝色与绿色增强
import cv2
import numpy as np
img = cv2. imread( 'image0.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]
b = b * 1.5
g = g * 1.3
if b > 255 :
b = 255
if g > 255 :
g = 255
dst[ i, j] = ( b, g, r)
cv2. imshow( 'dst' , dst)
cv2. waitKey( 0 )
八、油画效果
油画效果实现步骤
①.gray 灰度化 ②.将图片分割为若干个小方块。统计这些小方块中每个像素的灰度值,比如7 * 7 ,10 * 10 ③.将0-255划分段,并将第二步的映射到对应段范围中:如划分4个段,每个段有64个等级。0-63 第1段;64-127第2段 ④.例如:这时有一个像素点.灰度值是10,那么他就在0-63这个点
找到每个方块中灰度等级最多的所有像素,count 并求取这些像素的均值 用统计出来的平均值,替代原来的像素值
import cv2
import numpy as np
img = cv2. imread( 'image0.jpg' , 1 )
cv2. imshow( 'src' , 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 ) :
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] + 1
currentMax = array1[ 0 ]
l = 0
for 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 )