OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~

opecv浅记

这篇博客从代码,理论以及一些实际操作角度讲解像素运算

长文

文章目录

  • opecv浅记
  • 像素点的运算
    • 1.像素点
    • 2.对像素点运算
      • ①.普通运算
      • ②.逻辑运算
    • 3.简单应用及其原理
      • ①.图像的对比度与亮度操作
      • ②.图像融合(凯隐和拉亚斯特,原谅博主中二了。:joy:)
      • ③.炫彩logo
      • ④.动态提取彩色的颜色帧
  • 总结

像素点的运算

像素点的运算即,基于OpenCV可调用API的运算,或者以numpy做一些简易的运算,但是还是更偏向于与直接调用API,它一般要比我们用numpy实现的算法高效很多。

1.像素点

在第一篇OpenCV的文章中,我们已经提过,一般情况下,一个图片的包含了,高,宽,通道数,三个指标。在RBG色彩空间中,每个通道数对应三原色中的一种,总共三个通道。

0——蓝
1——绿
2——红
可用 image.shape将高,宽,通道数调出。

所谓的像素点,其实就是在(0,0,0)到 (高,宽,3)区间内的点,我们假设取一个(x,y,z)
那么x便是高度,y为宽度,而z便是当前通道数,也可以说当前维度,先前曾写过遍历每个像素点并进行计算的代码,如下:

def get_image_info(image):
    height=image.shape[0]
    width=image.shape[1]
    channels=image.shape[2]
    print('height: {},width: {},channels: {}'.format(image.shape[0],image.shape[1],image.shape[2]))
    for i in range(height):
        for j in range(width):
            for c in range(channels):
                cv=image[i,j,c]
                image[i,j,c]=255-cv
    return image

其本质为,对一个图像的取反操作。
对三维空间来说,很容易理解,那么我们再来看每个像素点的值,在读图时,我们可以用dtype方法将数据位数输出出来,通常为uint8,即无符号八位,这就跟像素点的取值产生了关系,无符号八位的取值为0~255,这与像素点的取值范围相同,而255对应着最亮,0对应的最暗,通道0的每个点若都取到255,则为一张纯蓝色的图,先前已经说过,这里提出只是更透彻地明白像素点的含义。

2.对像素点运算

对像素点的运算可以笼统的分为两大类:普通运算与逻辑运算

①.普通运算

加减乘除,加权加法,均值与方差
像素运算,更可以从矩阵的每个元素的运算来理解。由简入繁,从简单的来说,如下是两个三维矩阵这里只打印其中一个,对应三通道:

import numpy as np

array_1=np.ones([2,2,3],np.uint8)
array_2=np.ones([2,2,3],np.uint8)
print(array_1)

OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第1张图片
像素点的加法,是对其中每个元素进行相加。得到如下:
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第2张图片
接下来对图像文件进行操作,加法:

def __add__(image_1,image_2):
    re_image=cv.add(image_1,image_2)
    return re_image

结果如下,这时候我们如果将,他们按矩阵打印出来,就会发现,与上面的简单加法是相同的。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第3张图片
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第4张图片
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第5张图片减法,乘法,除法类似:

#像素运算,相减,从1中扣去2
def __subtract__(image_1,image_2):
    return cv.subtract(image_1,image_2)
#像素,相除操作,除以2
def __divide__(image_1,image_2):
    return cv.divide(image_1,image_2)
#像素的乘法
def __multiply__(image_1,image_2):    
    return cv.multiply(image_1,image_2)

这里我们就不难想到了,既然规定范围为0~255那么,乘法在很大概率上都会超过255,除法在很大概率上都会很小,因此乘法得到的图像白色居多,而除法得到的图像黑色居多。

加权加法:

cv2.addWeighted(image1,w1,image2,w2,b)

将它的返回值视为一个y的话,其实它是对每个像素点进行这样的计算:
在这里插入图片描述取均值
这里的均值取得是每个通道图的均值,即假设有三个通道,那么返回的应该是一个四元组,前三元每一元对应每个通道图的所有值所求的均值,最后一元应该是alpha通道,对应透明度,可以稍作验证:

import numpy as np
import cv2 as cv



array_1=np.ones([2,2,3],np.uint8)
array_2=np.ones([2,2,3],np.uint8)
array_3=np.ones([2,2,3],np.uint8)*2
print(array_3)
print(cv.mean(array_3))

结果:
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第6张图片
没什么问题。
方差与均值
可调用以下API

import numpy as np
import cv2 as cv



array_1=np.ones([2,2,3],np.uint8)
array_2=np.ones([2,2,3],np.uint8)
array_3=np.ones([2,2,3],np.uint8)*2
print(array_3)
print(cv.meanStdDev(array_3))

结果:第一个array为上面所说,第二个array为方差
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第7张图片

②.逻辑运算

逻辑运算,位运算,在很多人在高中就已经接触到了二进制,但是对于二进制的按位运算应该还是在大学开始的。位运算先前有写过博客,对于像素的位运算,我们只说三种
按位与,按位或,按位取反,在此之前,我们需要说一下三种简单的位运算。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第8张图片OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第9张图片
按位取反。。。淦,之前的博客没写,没法截图偷懒了。。。
按位取反很简单,对0取1,对1取0,对于001101来说就是110010
对于像素点的逻辑运算需要借用opencv的API:

#逻辑运算
def __logicopera__(image_1,image_2):
    cv.imshow('logic_1',cv.bitwise_and(image_1,image_2))
    cv.imshow('logic_2',cv.bitwise_or(image_1,image_2))
    cv.imshow('logic_3',cv.bitwise_not(image_1))

其结果:

从像素点的角度来说,主要说一下取反的操作,这里的取反其实是与开头那段代码的作用不谋而合的,即对每个像素点进行255-的操作。至于按位与和按位或,应该可以自己理解。

3.简单应用及其原理

在介绍完几种运算,可以实现一些简单的应用,
这里还要说到一个东西,掩膜,我们利用inRange方法提取出来的东西,通称之为掩掩膜,对于该方法陌生的小伙伴:点击这里,最后的代码有细说。掩膜,即提取图像的某部分后,仅仅该部分为白色,其余为黑色。很多操作都需要用到掩膜。

①.图像的对比度与亮度操作

调用OpenCVAPI,加权加法运算

#图像的对比度与亮度操作 通过加权运算实现
def contrast__brightness(image,c,b):
    #通过原图与黑图的加权运算
    h,w,ch=image.shape
    blank_image=np.zeros([h,w,ch],image.dtype)
    dst=cv.addWeighted(image,c,blank_image,1-c,b)
    cv.imshow('dst',dst)

如下为效果,左图为原图,该代码可用于简单的美白。
原理:创建一张为0的黑图,对该图和原图进行加权运算,因为为0的黑图,不论是乘谁都为0,这样就不会影响原图,不会降低原图的像素点值,
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第10张图片

②.图像融合(凯隐和拉亚斯特,原谅博主中二了。)

import cv2 as cv
import numpy as np


#图片融合
def png_fuse(image_1,image_2):
    c=0.1
    b=int(input("输入亮度增加单位:"))
    cv.namedWindow('show',cv.WINDOW_AUTOSIZE)
    while True:
        add_png=cv.addWeighted(image_1,c,image_2,1-c,b)
        cv.imshow('show',add_png)
        a=cv.waitKey(0)
        if a==32 :
            c+=0.1
            continue
        elif a==27 :
            cv.imwrite('pen_fuse.png',add_png)
            cv.destroyAllWindows()
            break
    print('遍历结束')
src_1=cv.imread('ky_1.jpg')
src_1=cv.resize(src_1,(400,400))
src_2=cv.imread('ky_2.jpg')
src_2=cv.resize(src_2,(400,400))
png_fuse(src_1,src_2)

结果如下,是不是狂拽酷炫吊炸天。这样就已经到了OpenCV有意思的地方了。
原理:加权运算,不为零的像素点,在负数的运算下,使得不同的像素点,达到了对比的效果,凸显出了蓝凯的形象。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第11张图片

③.炫彩logo

#将一张图片的logo融入到另一张图片中,或者对某一张图片的logo进行炫彩
import cv2 as cv
import numpy as np

def opera(image_1,image_2):
    hsv=cv.cvtColor(image_1,cv.COLOR_BGR2HSV)
    mask=cv.inRange(hsv,np.array([0,0,221]),np.array([180,30,255]))
    mask=cv.bitwise_and(image_2,image_2,mask=mask)
    cv.imshow('logo',mask)
    
    
    
    
src_1=cv.imread('same_3.jpg')
h,w,ch=src_1.shape
src_2=cv.imread('big_1.jpg')
src_2=cv.resize(src_2,(w,h))
cv.namedWindow('input_1',cv.WINDOW_AUTOSIZE)
cv.imshow('input_1',src_2)
cv.imshow('input_2',src_1)
opera(src_1,src_2)
cv.waitKey(0)
cv.destroyAllWindows()

原理,利用inRange提取出,仅仅包含logo的掩膜,在掩膜中,除logo外其余皆为黑色,也就是0,利用掩膜和图像进行逻辑与运算即可。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第12张图片

④.动态提取彩色的颜色帧

import cv2 as cv
import numpy as np


#动态提取视频中的固定颜色帧
def get_video_color():
    #调用摄像头 获取影像文件
    capture=cv.VideoCapture(0)
    while True:
        #读取帧数与布尔值
        ret,frame=capture.read()
        #转为hsv色彩空间
        hsv=cv.cvtColor(frame,cv.COLOR_BGR2HSV)
        #设置颜色提取范围
        lower_index=np.array([35,43,46])
        upper_index=np.array([255,255,255])
        #提取颜色
        mask=cv.inRange(hsv,lower_index,upper_index)
        #颜色融合
        dist=cv.bitwise_and(frame,frame,mask=mask)
        #show
        cv.imshow('video',frame)
        cv.imshow('dist',dist)
        #等待指令为esc时,停止
        c=cv.waitKey(40)
        if c==27:
            break
#src=cv.imread('test_1.png')
#cv.namedWindow('input_1',cv.WINDOW_AUTOSIZE)
#cv.imshow('input_1',src)
get_video_color()
cv.waitKey(0)
cv.destroyAllWindows()

这里的颜色范围设置,在转化为HSV色彩空间后
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第13张图片

这里是视频不太好放出来,截张图片就行,可以看出效果还是很好的。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第14张图片

总结

总体看来,像素点的运算无非就是那么些。
OpenCV像素点的计算,好家伙,直接降龄化教学。。。代码对图片的神奇操作~~~~~~_第15张图片

也不难发现,那么多的花里胡哨的操作其本质就是对于像素点进行各种操作,因此,像素点的运算是一定要熟练掌握的。

你可能感兴趣的:(机器学习,opencv,计算机视觉,python)