计算机视觉加强之图像特效与线段文字绘制

一.图像特效介绍

1.灰度处理:彩色图片灰度化
  • 对于彩色图片有三个颜色通道:RGB
  • 对于灰度图片如果也是三个颜色通道,则RGB值是相等的
2.底板效果(灰度)
  • 彩色底板是通过当前RGB取反得到的
3.马赛克效果
  • 将周边的像素点用同一个像素点取代
4.毛玻璃效果
  • 将像素用随机像素来替代
5.颜色映射
  • 利用RBG表进行颜色统一映射
6.边缘检测
  • 卷积运算
7.浮雕效果
  • 在边缘检测上添加底板

二.图像灰度处理

1.开发思路
  • 方法1:使用imread方法实现颜色直接转换处理
  • 方法2:使用cvtColor方法实现颜色转换
  • 方法3:源码实现图像灰度处理
    • 灰度图像R=G=B
  • 方法4:心理学计算公式实现图像灰度处理
    • gray = r*0.299+g*0.587+b*0.114
2.实例代码
  • 方法1实例代码

    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)
    
  • 方法2实例代码

    import cv2
    img = cv2.imread('image0.png',1)
    dst = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#完成颜色空间转换,参数:原始待转换图片的数据,颜色转换的方式
    cv2.imshow('src',dst)
    cv2.waitKey(0)
    
  • 方法3实现代码

    import cv2
    import numpy as np
    img = cv2.imread('image0.png',1)
    imgInfo = img.shape
    height = imgInfo[0]
    width = imgInfo[1]
    #RGB R=G=B Gray (R+G+B)/3
    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实现代码

    import cv2
    import numpy as np
    img = cv2.imread('image0.png',1)
    imgInfo = img.shape
    height = imgInfo[0]
    width = imgInfo[1]
    #RGB R=G=B Gray (R+G+B)/3
    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)
    
3.灰度算法优化
  • 灰度图像是所有图像特效的基础
  • 灰度图像强调算法的实时性
  • 算法优化原则:定点运算时间 < 浮点运算时间 移位运算时间 < 加减运算时间 < 乘除运算时间
  • 优化r*0.299+g*0.587+b*0.114公式
    • 浮点转定点int(x)
    • gray = (r*1+g*2+b*1)/4相当于先左移两位,再右移两位【肯定有误差的】
    • 进一步优化gray = (r+(g<<1)+b)>>2,将浮点运算变成定点运算后,将乘除运算编程移位运算
4.实例代码
import cv2
import numpy as np
img = cv2.imread('image0.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
#RGB R=G=B Gray (R+G+B)/3
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)

三.颜色反转

1.开发思路
  • 灰度图片颜色反转:对于灰度图片取值范围是0-255,颜色反转是255-当前灰度值
  • 彩色图片颜色反转:对于RGB有3个通道,每一个像素值都是255-当前的像素值(如R=255-R,G=255-G,B=255-B)
2.实例代码
  • 灰度图片颜色反转实例代码

    import cv2
    import numpy as np
    img = cv2.imread('image0.png',1)
    imgInfo = img.shape
    height = imgInfo[0]
    width = imgInfo[1]
    gary = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    dst = np.zeros((height,width,3),np.uint8)#其中3表示的是一个像素由几种颜色构成,彩色为3,灰色为1
    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.png',1)
    imgInfo = img.shape
    height = imgInfo[0]
    width = imgInfo[1]
    dst = np.zeros((height,width,3),np.uint8)#其中3表示的是一个像素由几种颜色构成,彩色为3,灰色为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)
    

四.马赛克效果

1.开发设计
  • 马赛克效果的窗体范围:如行100-300,列100-200
  • 每一个马赛克都有一个小窗口,有矩形的马赛克(10*10),也有圆形的马赛克【本例中使用矩形的马赛克】
  • 使用10*10像素块中左上角的像素替换像素块中所有的像素
2.实例代码
import cv2
import numpy as np
img = cv2.imread('image0.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
for m in range(100,300):
    for n in range(100,200):
        #选中一个元素,替换调10*10中所有的像素点,让10*10中保持一致
        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)

五.毛玻璃

1.开发设计
  • 毛玻璃的思想与马赛克一致,但不是使用固定像素进行像素的替换,而是使用随机的像素替换像素块中的内容
2.实例代码
import cv2
import numpy as np
import random
img = cv2.imread('image0.png',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
dst = np.zeros((height,width,3),np.uint8)
mm = 8#设置随机数的范围在水平和垂直上均为8,即8*8的像素块中取随机像素
for m in range(0,height-mm):
	for n in range(0,width-mm):
        index = int(random.random()*8)#random.random()生成的随机数是0-1,*8后,随机数的范围就是0-8
        (b,g,r) = img[m+index,n+index]
        dst[m,n] = (b,g,r)
cv2.imshow('dst',dst)
cv2.waitKey(0)
3.注意事项
  • 最右侧和最下侧都会有8个黑色区域,是因为垂直和水平方向各减去了8,默认填充为0,即为黑色区域

六.图片融合

1.开发设计
  • 目标图片=src1*a系数+src2*(1-a系数)
2.实例代码
import cv2
import numpy as np
img0 = cv2.imread('image0.png',1)#读取图片1
img1 = cv2.imread('image1.png',1)#读取图片2
imgInfo = img0.shape#因为图片1和2的宽高一样,通过此处获得图片的宽高信息
height = imgInfo[0]
width = imgInfo[1]
#ROI感兴趣范围(即将原图扣除一部分,此部分的宽度为源高度的1/2,高度为源高度的1/2)
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)#第一个图片的权重和第二个图片的权重都是0.5。实现的是权重的计算:目标图片=src1*a系数+src2*(1-a系数)。
#参数1:src1,参数2:src1权重,参数3:src2,参数4:src2权重
cv2.imshow('dst',dst)
cv2.waitKey(0)

七.边缘检测

1.开发设计
  • 完成图像的灰度处理,基于灰度图像的(将彩色图片转换成灰度图片)
  • 执行高斯滤波,去除噪声的干扰
  • 调用opencv中的canny方法实现边缘检测
2.实例代码
import cv2
import numpy as np
import random
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)#实现高斯滤波,参数1:灰度图像数据;参数2:模板大小
dst = cv2.Canny(img,50,50)#参数1:传递图片的数据,参数2:门限值(如果图片经过卷积之后的值大于这个门限,则默认为边缘点,否则则视为非边缘点)
cv2.imshow('dst',dst)
cv2.waitKey(0)

在这里插入图片描述

3.源码实现sobel算法
  • 算法原理

    • 算子模板【分水平方向和竖直方向】

      #矩阵1
      [1  2  1
       0  0  0
       -1 -2 -1]
      #矩阵2
      [1  0  -1
       2  0  -2
       1  0  -1]
      
    • 图片卷积【不是矩阵行列式计算,是矩阵中的数值对应相乘得到的结果】

      #eg
      #源模板[1 2 3 4]
      #算子模板[a b c d]
      #结果a*1+b*2+c*3+d*4 = dst 结果称之为梯度,有水平方向和竖直方向两种情况
      
    • 阈值判决

      #算子模板1(竖直方向上的算子)与垂直方向上的图片进行卷积之后得到的结果为a,称为竖直上的梯度
      #算子模板2(水平方向上的算子)与水平方向上的图片进行卷积之后得到的结果为b,称为水平上的梯度
      #f值为sqrt(a*a+b*b),与门限进行判决,如果>判决门限则为边缘;如果<判决门限则为非边缘
      
  • 实例代码

    import cv2
    import numpy as np
    import math
    img = cv2.imread('image1.jpg',1)#读取图片1
    imgInfo = img.shape#因为图片1和2的宽高一样,通过此处获得图片的宽高信息
    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):#卷积运算的时候会从左上角[1,1]的位置开始,单位是3*3,所以需要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]*1-gray[i,j+2]*1+gray[i+1,j]*2-gray[i+1,j+2]*2+gray[i+2,j]*1-gray[i+2,j+2]*1
            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)
    

在这里插入图片描述

八.浮雕效果

1.开发设计
  • 浮雕效果也是计算梯度
    • 浮雕效果的计算公式新像素值=gray0-gray1+150,相邻像素之差加上固定值
2.实例代码
import cv2
import numpy as np
img = cv2.imread('image1.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#newP = gray0-gray1+150
dst = np.zeros((height,width,1),np.uint8)
for i in range(0,height):
    for j in range(0,width-1):
        grapP0 = 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)

在这里插入图片描述

九.颜色映射

1.开发思路
  • 通过查找表将原始RGB值替换成新的RGB值
  • 增加蓝色系的模拟变换公式:b=b*1.5,g=g*1.3
2.实例代码
import cv2
import numpy as np
img = cv2.imread('image1.jpg',1)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]
cv2.imshow('src',img)
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)

在这里插入图片描述

十.油画特效

1.开发思路
  • 完成彩色图片到灰度图片的转换
  • 将图片分割为若干个小方块,统计每个小方块中像素的灰度值
  • 将0-255的灰度值划分为几个等级,并把第二部处理的结果映射到这个范围内
  • 找到每个方块中灰度等级最多的像素(灰度段中像素的个数统计),并求取像素的均值
  • 用统计出来的平均值替换原来的像素值
2.实例代码
import cv2
import numpy as np
img = cv2.imread('image1.jpg',1)
cv2.imshow('src',img)
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,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]#array1中哪一个等级段获取的像素值最多
        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)

在这里插入图片描述

十一.线段绘制

1.开发思路
  • 绘制空白模板
  • 使用cv2.line()绘制线段
    • 参数1:目标图片数据
    • 参数2:线段起始位置
    • 参数3:线段终止位置
    • 参数4:当前颜色
    • 参数5:线条宽度
    • 参数6:线条类型
2.实例代码
import cv2
import numpy as np
newImageInfo = (500,500,3)#(宽,高,彩色RGB)
dst = np.zeros(newImageInfo,np.uint8)
#绘制线段
cv2.line(dst,(100,100),(400,400),(0,0,255))#参数1:目标图片数据;参数2:线段起始位置;参数3:线段终止位置;参数4:当前颜色
cv2.line(dst,(100,200),(400,200),(0,255,255),20)#参数5:线条宽度
cv2.line(dst,(100,300),(400,300),(0,255,0),20,cv2.LINE_AA)#参数6:线条类型,cv2.LINE_AA比没有设置该类型的边线更光滑;额
#绘制三角形(即闭合的三条线段)
cv2.line(dst,(200,150),(50,250),(25,100,255))
cv2.line(dst,(50,250),(400,380),(25,100,255))
cv2.line(dst,(400,380),(200,150),(25,100,255))

cv2.imshow('dst',dst)
cv2.waitKey(0)

在这里插入图片描述

十二.矩形圆形任意多边形绘制

1.开发思路
  • 绘制矩形cv2.rectangle()
    • 参数1:目标图片;参数2:左上角坐标;参数3:右下角坐标;参数4:颜色填充;参数5:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度
  • 绘制圆形cv2.cicle()
    • 参数1:目标图片;参数2:表明圆心;参数3:半径;参数4:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度
  • 绘制椭圆形cv2.ellipse()
    • 参数1:目标图片;参数2:表明圆心;参数3:表明轴的长度(长轴、短轴);参数4:偏转角度;参数5:圆弧起始角度;参数6:圆弧终止角度;参数7:颜色填充;参数8:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度 #绘制任意多边形
2.实例代码
import cv2
import numpy as np
newImageInfo = (500,500,3)
dst = np.zeros(newImageInfo,np.uint8)
#绘制矩形
cv2.rectangle(dst,(50,100),(200,300),(255,0,0),-1)#参数1:目标图片;参数2:左上角坐标;参数3:右下角坐标;参数4:颜色填充;参数5:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度
#绘制圆形
cv2.circle(dst,(250,250),(50),(0,255,0),2)#参数1:目标图片;参数2:表明圆心;参数3:半径;参数4:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度
#绘制椭圆形
cv2.ellipse(dst,(256,256),(150,100),0,0,180,(255,255,0),-1)#参数1:目标图片;参数2:表明圆心;参数3:表明轴的长度(长轴、短轴);参数4:偏转角度;参数5:圆弧起始角度;参数6:圆弧终止角度;参数7:颜色填充;参数8:表示内容是否要填充,-1表示需要填充,大于0则表示线条宽度
#绘制任意多边形
points = np.array([[150,50],[140,140],[200,170],[250,250],[150,50]],np.int32)
points = points.reshape((-1,1,2))#实现维度转换
cv2.polylines(dst,[points],True,(0,255,255))
cv2.imshow('dst',dst)
cv2.waitKey(0)

在这里插入图片描述

十三.文字图片绘制

1.思路设计
  • 绘制文字
    • 使用cv2.putText()绘制文字
  • 绘制图片
    • 使用cv2.resize(源图片,(宽,高))重置图片大小
2.实例代码
  • 绘制文字
import cv2
import numpy as np
img = cv2.imread('image0.png',1)
font = cv2.FONT_HERSHEY_SIMPLEX#定义字体
cv2.rectangle(img,(150,100),(300,200),(0,255,0),3)
cv2.putText(img,'this is flow',(100,200),font,1,(200,100,255),2,cv2.LINE_4)#参数1:目标图片;参数2:文字内容;参数3:写入的坐标;参数4和参数5:字体和字体大小;参数6:颜色;参数7:粗细信息;参数8:线条类型
cv2.imshow('dst',img)
cv2.waitKey(0)

在这里插入图片描述

  • 绘制图片
import cv2
img = cv2.imread('image0.png',1)
height = int(img.shape[0]*0.2)
width = int(img.shape[1]*0.2)
imgResize = cv2.resize(img,(width,height))#重置图片宽高得到新矩阵
for i in range(0,height):
    for j in range(0,width):
        img[i+50,j+100] = imgResize[i,j]
cv2.imshow('dst',img)
cv2.waitKey(0)

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值