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)

ios 取像素点 矩阵算法 像素点个数怎么算_ios 取像素点 矩阵算法


像素点的加法,是对其中每个元素进行相加。得到如下:

ios 取像素点 矩阵算法 像素点个数怎么算_python_02


接下来对图像文件进行操作,加法:

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

结果如下,这时候我们如果将,他们按矩阵打印出来,就会发现,与上面的简单加法是相同的。

ios 取像素点 矩阵算法 像素点个数怎么算_计算机视觉_03

ios 取像素点 矩阵算法 像素点个数怎么算_opencv_04


ios 取像素点 矩阵算法 像素点个数怎么算_python_05


ios 取像素点 矩阵算法 像素点个数怎么算_python_06

减法,乘法,除法类似:

#像素运算,相减,从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的话,其实它是对每个像素点进行这样的计算:

ios 取像素点 矩阵算法 像素点个数怎么算_ios 取像素点 矩阵算法_07

取均值

这里的均值取得是每个通道图的均值,即假设有三个通道,那么返回的应该是一个四元组,前三元每一元对应每个通道图的所有值所求的均值,最后一元应该是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))

结果:

ios 取像素点 矩阵算法 像素点个数怎么算_python_08


没什么问题。

方差与均值

可调用以下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为方差

ios 取像素点 矩阵算法 像素点个数怎么算_像素点_09

②.逻辑运算

逻辑运算,位运算,在很多人在高中就已经接触到了二进制,但是对于二进制的按位运算应该还是在大学开始的。位运算先前有写过博客,对于像素的位运算,我们只说三种

按位与,按位或,按位取反,在此之前,我们需要说一下三种简单的位运算。

ios 取像素点 矩阵算法 像素点个数怎么算_python_10

ios 取像素点 矩阵算法 像素点个数怎么算_ios 取像素点 矩阵算法_11


按位取反。。。淦,之前的博客没写,没法截图偷懒了。。。

按位取反很简单,对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))

其结果:

ios 取像素点 矩阵算法 像素点个数怎么算_opencv_12


从像素点的角度来说,主要说一下取反的操作,这里的取反其实是与开头那段代码的作用不谋而合的,即对每个像素点进行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,这样就不会影响原图,不会降低原图的像素点值,

ios 取像素点 矩阵算法 像素点个数怎么算_ios 取像素点 矩阵算法_13

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

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有意思的地方了。

原理:加权运算,不为零的像素点,在负数的运算下,使得不同的像素点,达到了对比的效果,凸显出了蓝凯的形象。

ios 取像素点 矩阵算法 像素点个数怎么算_像素点_14

③.炫彩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,利用掩膜和图像进行逻辑与运算即可。

ios 取像素点 矩阵算法 像素点个数怎么算_ios 取像素点 矩阵算法_15

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

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色彩空间后

ios 取像素点 矩阵算法 像素点个数怎么算_opencv_16

这里是视频不太好放出来,截张图片就行,可以看出效果还是很好的。

ios 取像素点 矩阵算法 像素点个数怎么算_python_17

总结

总体看来,像素点的运算无非就是那么些。

ios 取像素点 矩阵算法 像素点个数怎么算_像素点_18

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