opencv

安装

在python中安装pip install 包的名字,pip报错需要再环境变量中添加python的pip所在路径,pythpon也是一样。
环境变量的添加
在这里插入图片描述
数据处理模块
numpy
pandas
matplotlib

图像处理
opencv-python
tensorflow
keras

opencv图像处理

图像最小单元-像素

计算机中像素的值通常用8位的无符号整型表示0-255
假设将图片颜色分位256级,即黑白图片,单通道图片
在这里插入图片描述

RGB 三原色
·我们生活中的图像都是有RGB三原色构成的∶R是Red红色,G是Green绿色,B是Blue蓝色。。在计算机中RGB这三个颜色的取值通常也是在0-255之间。彩色图片有三个通道,所以是属于三通道图片。

操作图片

读 显示 保存

import cv2
import matplotlib.pyplot as plt

#不能有中文?还是编码格式的问题?
#最好还是尽量避免使用特殊字符和非英文字符的路径,以确保代码的可移植性和稳定性。
# image_path = r"E:/AI/AI工程师计算机视觉方向/03-计算机视觉库opencv/03-计算机视觉库opencv/第二章opencv/CLASSDATA_第三门_计算机视觉库OpenCV/0.体验课资料/image.jpg"
# image = cv2.imread(image_path)

# image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)  #
image = cv2.imread("image.jpg")
print("width=%d pix"%(image.shape[1]))
print("height=%d pix"%(image.shape[0]))
print("channels=%d "%(image.shape[2]))


plt.imshow(image)

# plt.axis
# 通常用于调整图表的显示范围和坐标轴的外观。
# 具体选择哪种用法取决于你想要达到的效果。
plt.axis('off')
plt.show()

颜色不一致
在这里插入图片描述

原因:plt显示图片是RGB格式
opencv读图是BGR
添加

 image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)

操作图片内容

import cv2
import matplotlib.pyplot as plt


# cv2.imread返回值是一个代表图像的多维NumPy数组,这个数组包含图像的像素值。
# 具体来说,cv2.imread() 返回一个NumPy数组,
# 其形状取决于图像的维度和通道数。如果图像是单通道(灰度图像),
# 则返回的数组形状为 (rows, cols);如果图像是三通道(彩色图像),
# 则返回的数组形状为 (rows, cols, 3),其中 rows 表示图像的高度,
# cols 表示图像的宽度。
image = cv2.imread("image.jpg")
(h,w,c) = image.shape
print(image.shape)


(b,g,r) = image[0,0]
bgr=image[0,0]
print((b,g,r))
print(bgr)
print(image[0,0])


image[0,0] = (0,0,255)
bgr=image[0,0]
print(bgr)

#w//2 中的 // 是Python中的整数除法运算符,
# 它表示取整除 - 返回商的整数部分。
cX, cY = (w//2, h//2)
tl = image[0:cY, 0:cX]
plt.imshow(tl)
plt.axis('off')
plt.show()

tr = image[0:cY, cX:w]
bl = image[h//2:h, 0:w//2]
br = image[h//2:h, w//2:w]


def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()


show(tl)
show(tr)
show(bl)
show(br)



image[h//2:h, 0:w//2] = (255,0,0)

show(image)


图片的平移转换


import cv2
import matplotlib.pyplot as plt
import numpy as np



def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

#读进来是BGR 显示为RGB所以转换成RGB
def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image


image = imread('image.jpg')
#
M = np.float32([[1,0,250],[0,1,500]])
shifted = cv2.warpAffine(image,M,(image.shape[1],image.shape[0]))

show(shifted)

解释一下代码的关键部分:

导入模块:

import cv2
import matplotlib.pyplot as plt
import numpy as np

自定义显示函数:

def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

这个函数用于显示图像,隐藏坐标轴。

读取并转换图像:

def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    return image

这个函数用于读取图像并将其从BGR颜色空间转换为RGB颜色空间,以便在Matplotlib中正确显示。

读取并处理图像:

image = imread('image.jpg')

这里调用了自定义的 imread 函数,读取并处理了名为 ‘image.jpg’ 的图像。

平移图像:

M = np.float32([[1, 0, 250], [0, 1, 500]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

这里使用了OpenCV的 cv2.warpAffine 函数来进行仿射变换,实现了对图像的平移操作。M 是仿射矩阵,指定了平移的偏移量。

显示平移后的图像:
show(shifted)
这里调用自定义的 show 函数来显示平移后的图像。

整体上,这段代码完成了读取图像、转换颜色空间、图像平移、显示图像的操作。

对于warpAffine函数的解释

cv2.warpAffine() 是OpenCV库中用于进行二维仿射变换的函数。仿射变换可以用于平移、旋转、缩放和剪切图像,是一种线性变换。

函数原型如下:

dst = cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]])

参数说明:

src:要进行变换的输入图像。
M:2x3变换矩阵,数据类型为np.float32,指定变换的方式和参数。
dsize:输出图像的大小,通常为 (width, height)。
dst:输出图像,可选参数。如果未提供,函数会创建一个与输入图像大小和深度相同的输出图像。
flags:插值方法的标志,用于指定如何计算非整数像素的值。
borderMode:用于推断边界像素的方法,通常使用默认值cv2.BORDER_CONSTANT。
borderValue:在边界模式为cv2.BORDER_CONSTANT时使用的边界值。

cv2.warpAffine() 将输入图像 src 按照变换矩阵 M 进行仿射变换,并将结果存储在输出图像 dst 中。这个函数可以实现图像的平移、旋转、缩放等操作。

例如,通过构建适当的仿射变换矩阵 M,可以对图像进行平移操作,如你代码中的平移示例:

M = np.float32([[1, 0, 250], [0, 1, 500]])
shifted = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

这里通过 M 指定了在x轴和y轴上的平移量,然后应用了 cv2.warpAffine() 函数实现平移操作。

旋转图片

import cv2
import matplotlib.pyplot as plt
import numpy as np


def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()


def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

image = imread('image.jpg')
show(image)

image = imread('image.jpg')

(h,w) = image.shape[0:2]
(cx,cy) = (w/2,h/2)

#cx,cy-旋转中心
#45-逆时针旋转45度
# 1.0 缩放
Matrix = cv2.getRotationMatrix2D((cx,cy),45,1.0)
image = cv2.warpAffine(image,Matrix,(w,h))
show(image)

image = imread('image.jpg')
(h,w) = image.shape[:2]
(cX,cY) = (w/2,h/2)

# (cX,cY)-旋转中心点
# 45-逆时针旋转45度
# 0.5-缩放
M = cv2.getRotationMatrix2D((cX,cY), 45, 0.5)
image = cv2.warpAffine(image, M, (w,h))
show(image)


image = imread('image.jpg')
(h,w) = image.shape[:2]
(cX,cY) = (w/2,h/2)

# (cX-200,cY-200)-旋转中心点
# 45-逆时针旋转45度
# 1.0-缩放
M = cv2.getRotationMatrix2D((cX-200,cY-200), 45, 1.0)
image = cv2.warpAffine(image, M, (w,h))
show(image)

缩放



from imutils import *
"""
import cv2
import matplotlib.pyplot as plt
import numpy as np

def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()
    
def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

"""

image = imread ('image.jpg')
show(image)
print(image.shape)


width = 150
height = 150
image = cv2.resize(image,(width,height))
show(image)
print(image.shape)


#等比例缩放
image = imread('image.jpg')
width = 80
high = int(image.shape[0]*width/image.shape[1])
image = cv2.resize(image, (width, high))
show(image)
print(image.shape)



# 5种插值方法:
# 最邻近
image = imread('image.jpg')
width = 150
high = 150
image = cv2.resize(image, (width, high), interpolation=cv2.INTER_NEAREST)
show(image)
print(image.shape)



# 5种插值方法:
# 双线性
image = imread('image.jpg')
width = 150
high = 150
image = cv2.resize(image, (width, high), interpolation=cv2.INTER_LINEAR)
show(image)
print(image.shape)




# 5种插值方法:
# 基于像素区域
image = imread('image.jpg')
width = 150
high = 150
image = cv2.resize(image, (width, high), interpolation=cv2.INTER_AREA)
show(image)
print(image.shape)


# 5种插值方法:
# 立方插值
image = imread('image.jpg')
width = 150
high = 150
image = cv2.resize(image, (width, high), interpolation=cv2.INTER_CUBIC)
show(image)
print(image.shape)



# 5种插值方法:
# 兰索斯插值
image = imread('image.jpg')
width = 150
high = 150
image = cv2.resize(image, (width, high), interpolation=cv2.INTER_LANCZOS4)
show(image)
print(image.shape)

cv2.resize() 函数是OpenCV库中用于图像大小调整的函数,其中 interpolation 参数用于指定插值方法,以确定如何处理在调整大小过程中产生的新像素的值。插值是根据现有像素值推断新像素值的过程。

以下是常用的五种插值方法以及它们的解释:

最近邻插值 (cv2.INTER_NEAREST)
最近邻插值是一种简单的插值方法,它选择最接近新像素位置的原始像素的值作为新像素的值。这种方法计算速度快,但可能会引入锯齿状的图像。

双线性插值 (cv2.INTER_LINEAR)
双线性插值是一种线性插值方法,它考虑了新像素位置周围4个原始像素的值,并使用线性加权平均计算新像素的值。这种方法对图像进行了平滑处理,比最近邻插值更精确。

双三次插值 (cv2.INTER_CUBIC)
双三次插值是一种更复杂的插值方法,它考虑了更多周围像素,并使用三次多项式来计算新像素的值。它比双线性插值更精确,但计算量更大。

区域插值 (cv2.INTER_AREA)
区域插值方法对像素进行区域关系重采样。它是一种高质量的插值方法,特别适用于缩小图像。

兰索斯插值 (cv2.INTER_LANCZOS4)
兰索斯插值是一种高质量的插值方法,使用兰索斯窗口函数对像素进行加权平均。它提供了最高的图像质量,但计算量也最大。

选择适当的插值方法取决于你的应用需求,通常情况下,双线性插值 (cv2.INTER_LINEAR) 是一种不错的通用选择,提供了较好的速度和图像质量。如果需要更高质量的调整大小,可以考虑双三次插值 (cv2.INTER_CUBIC) 或兰索斯插值 (cv2.INTER_LANCZOS4)。

人脸检测

# imutils.py
import cv2
import matplotlib.pyplot as plt
import numpy as np

def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()
    
def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image
from imutils import *


image = imread('face.png')
show(image)

# image:输入图像
# scaleFactor=1.1:这个是每次缩小图像的比例,默认是1.1
# minNeighbors=3:匹配成功所需要的周围矩形框的数目,每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3。
# minSize:匹配人脸的最小范围
# flags=0:可以取如下这些值:
# CASCADE_DO_CANNY_PRUNING=1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域
# CASCADE_SCALE_IMAGE=2, 正常比例检测
# CASCADE_FIND_BIGGEST_OBJECT=4, 只检测最大的物体
# CASCADE_DO_ROUGH_SEARCH=8 初略的检测


#级联分类器
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
rects = detector.detectMultiScale(image,scaleFactor=1.1,minNeighbors=2,minSize=(10,10),flags=cv2.CASCADE_SCALE_IMAGE)


for (x,y,w,h) in rects:
    #画出矩形框
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)

show(image)



def facedetect(image):
    image = imread(image)
    detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
    rects = detector.detectMultiScale(image,scaleFactor=1.1,minNeighbors=2,minSize=(10,10),flags=cv2.CASCADE_SCALE_IMAGE)

    for (x,y,w,h) in rects:
        #画矩形框
        cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)

    show(image)

facedetect('Solvay.jpg')


结果
在这里插入图片描述
在这里插入图片描述

画图

import numpy as np
import cv2
import matplotlib.pyplot as plt


def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()


image = np.zeros((300,300,3),dtype='uint8')


show(image)

#画线

green = (0,255,0)
cv2.line(image,(0,0),(300,300),green)
show(image)



blue = (0,0,255)
cv2.line(image,(300,0),(150,150),blue,5)
show(image)

#画矩形


red = (255,0,0)
cv2.rectangle(image,(10,10),(100,100),red,3)
show(image)

cv2.rectangle(image, (50,200), (220,280), green, -1)
show(image)


#画原型
image = np.zeros((300,300,3),dtype='uint8')
(cx,cy) = image.shape[1]//2,image.shape[0]//2

white = (255,255,255)
for r in range(0,151,15):
    cv2.circle(image,(cx,cy),r,white,2)
show(image)

image = np.zeros((300,300,3),dtype='uint8')
for i in range(10):
    # 半径取值
    radius = np.random.randint(5,200)
    # 颜色取值
    color = np.random.randint(0,255,size=(3,)).tolist()
    # 圆心取值
    pt = np.random.randint(0,300,size=(2,))
    # 画图
    cv2.circle(image, tuple(pt), radius, color, -1)
show(image)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

随机图片
在这里插入图片描述

翻转

import cv2
import matplotlib.pyplot as plt
import numpy as np



def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

image = imread('test.jpg')
show(image)


# 水平翻转
# 参数说明:
#
# src:要翻转的输入图像。
# flipCode:翻转操作的代码,指定了翻转的方式。
# flipCode 参数可以是以下三个值之一:
#
# 0(水平翻转):这个值表示对图像进行水平翻转,即左右翻转。
#
# 1(垂直翻转):这个值表示对图像进行垂直翻转,即上下翻转。
#
# -1(同时水平垂直翻转):这个值表示同时对图像进行水平和垂直翻转,即对角翻转。
#
# cv2.flip() 函数会将输入图像 src 按照指定的方式进行翻转,并将结果存储在输出图像 dst 中。如果不提供输出图像 dst,函数会创建一个与输入图像相同尺寸和深度的输出图像。
image = imread('test.jpg')
image = cv2.flip(image,flipCode=1)
show(image)

#垂直
image = imread('test.jpg')
image = cv2.flip(image,flipCode=0)
show(image)


#水平+垂直
image = imread('test.jpg')
image = cv2.flip(image,flipCode=-1)
show(image)


图像裁剪

from imutils import *


image = imread('test.jpg')
show(image)

image = image[0:200,50:200]
show(image)


image = imread('test.jpg')
image = image[200:,50:-50]
show(image)

图像算术

from imutils import *



image = imread('test.jpg')
#show(image)



#图像加法
print(cv2.add(np.uint8([200]),np.uint8([100])))
#普通加法
print(np.uint8([200])+np.uint8([101]))
# 这段代码演示了图像加法与普通数字加法之间的差异。
#
# 图像加法:
#
# python
# Copy code
# print(cv2.add(np.uint8([200]), np.uint8([100]))
# 这行代码使用了OpenCV的 cv2.add() 函数,它执行图像加法。在这里,我们将两个NumPy数组 np.uint8([200]) 和 np.uint8([100]) 传递给 cv2.add()。这两个数组包含了像素值(通常是0到255之间的整数),这是一个典型的图像处理场景。函数执行元素级相加,并确保结果值不超过255。所以,200 + 100 结果为 255。
#
# 普通加法:
#
# python
# Copy code
# print(np.uint8([200]) + np.uint8([100]))
# 这行代码执行了普通的数字加法,即将两个整数相加。在这里,np.uint8([200]) 和 np.uint8([100])
# 答案应该是 [44]。
# 这是因为无符号8位整数的范围是0到255,一旦结果超过255,会回绕到0。
# 所以,200 + 100 的结果 300 超过了255,回绕到0,因此结果是 [44]。
#
# 所以,主要的差异在于图像加法考虑了像素值不超过255的情况,因为图像通常使用8位表示,而普通的整数加法不做这种处理。
#
# 这种区别非常重要,因为在图像处理中,需要确保不会导致像素值溢出,否则图像可能会出现不合理的效果。图像加法会处理这一点,确保结果像素值在合理范围内。



#图像减法
print(cv2.subtract(np.uint8([200]),np.uint8([201])))
#普通减法
print(np.uint8([200])-np.uint8([202]))



image = imread('test.jpg')
#生成图像大小相同且像素值全为100的图片
M = np.ones(image.shape,dtype='uint8')*100
#所有像素+100
image = cv2.add(image,M)
show(image)

image = imread('test.jpg')
#生成图像大小相同像素全为100的图片
M = np.ones(image.shape,dtype='uint8')*100

#所有像素-100
image = cv2.subtract(image,M)
show(image)

结果:图像一次变量一次变暗
在这里插入图片描述

按位运算


# bitwise_and是对二进制数据进行“与”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“与”操作,1&1=1,1&0=0,0&1=0,0&0=0
# bitwise_or是对二进制数据进行“或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“或”操作,1|1=1,1|0=1,0|1=1,0|0=0
# bitwise_xor是对二进制数据进行“异或”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“异或”操作,1^1=0,1^0=1,0^1=1,0^0=0
# bitwise_not是对二进制数据进行“非”操作,即对图像(灰度图像或彩色图像均可)每个像素值进行二进制“非”操作,~1=0,~0=1



from imutils import *

rectangle = np.zeros((300,300,3),dtype='uint8')
white = (255,255,255)
cv2.rectangle(rectangle,(25,25),(275,275),white,-1)
show(rectangle)

circle = np.zeros((300,300,3),dtype='uint8')
cv2.circle(circle,(150,150),150,white, -1)
show(circle)


#AND
image = cv2.bitwise_and(rectangle,circle)
show(image)


#or
image = cv2.bitwise_or(rectangle,circle)
show(image)


#XOR
image = cv2.bitwise_xor(rectangle,circle)
show(image)



#NOT
image = cv2.bitwise_not(circle)
show(image)




遮挡图像

import cv2
import matplotlib.pyplot as plt
import numpy as np



def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()

def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)
    return image

image = imread('test.jpg')
show(image)
print(image.shape)


#创建遮挡

mask = np.zeros(image.shape,dtype='uint8')
white = (255,255,255)
cv2.rectangle(mask,(50,50),(250,350),white,-1)
show(mask)

#对图像进行遮挡
masked = cv2.bitwise_and(image,mask)
show(masked)


#创建遮挡
mask = np.zeros(image.shape,dtype='uint8')
white = (255,255,255)
cv2.circle(mask,(150,100),80,white,-1)
show(mask)



#对图片进行遮挡
masked = cv2.bitwise_and(image,mask)
show(masked)

这段代码演示了如何使用OpenCV创建遮挡(mask)并将其应用于图像。遮挡是一个与图像相同大小的数组,其中的像素值确定了图像中哪些区域会被显示,哪些区域会被隐藏。

以下是代码的主要部分:

加载并显示图像:

python
Copy code
image = imread(‘test.jpg’)
show(image)
这部分代码加载名为 ‘test.jpg’ 的图像,并显示它。

创建矩形遮挡:

python
Copy code
mask = np.zeros(image.shape, dtype=‘uint8’)
white = (255, 255, 255)
cv2.rectangle(mask, (50, 50), (250, 350), white, -1)
show(mask)
这段代码创建一个矩形形状的遮挡,该遮挡在原始图像上覆盖一个矩形区域,并将遮挡的像素值设置为白色。cv2.rectangle() 用于创建矩形,-1 表示填充整个矩形。

应用矩形遮挡:

python
Copy code
masked = cv2.bitwise_and(image, mask)
show(masked)
这部分代码将遮挡应用于原始图像,使用 cv2.bitwise_and() 函数,这会将遮挡区域的像素保留下来,而其他区域将被遮挡,显示为黑色。

创建圆形遮挡:

python
Copy code
mask = np.zeros(image.shape, dtype=‘uint8’)
white = (255, 255, 255)
cv2.circle(mask, (150, 100), 80, white, -1)
show(mask)
这段代码创建一个圆形遮挡,该遮挡覆盖原始图像上的一个圆形区域,并将遮挡的像素值设置为白色。

应用圆形遮挡:

python
Copy code
masked = cv2.bitwise_and(image, mask)
show(masked)
这部分代码将圆形遮挡应用于原始图像,同样使用 cv2.bitwise_and() 函数,这会将遮挡区域的像素保留下来,而其他区域将被遮挡,显示为黑色。

切分合并通道

import cv2
import matplotlib.pyplot as plt
import numpy as np


def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()


def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    return image


image = imread('test.jpg')
print(image.shape)


(R, G, B) = cv2.split(image)

print(R.shape)
print(G.shape)
print(B.shape)


merged=cv2.merge([R,G,B])

show(merged)
cv2.imshow('R',R)
cv2.imshow('G',G)
cv2.imshow('B',B)
cv2.waitKey(0)
cv2.destroyAllWindows()

这段代码演示了如何拆分和合并图像的RGB通道。RGB通道拆分可以将一幅彩色图像分成三个独立的通道:红色通道(R)、绿色通道(G)和蓝色通道(B)。

以下是代码的主要部分:

加载图像:

image = imread(‘test.jpg’)
这部分代码加载名为 ‘test.jpg’ 的彩色图像并将其存储在变量 image 中。

拆分RGB通道:

(R, G, B) = cv2.split(image)
这段代码使用OpenCV的 cv2.split() 函数将彩色图像拆分成红色通道(R)、绿色通道(G)和蓝色通道(B)。每个通道都是一个单通道的图像。

查看通道形状:

print(R.shape)
print(G.shape)
print(B.shape)
这部分代码打印出每个通道的形状,以便查看它们的维度信息。

合并RGB通道:

merged = cv2.merge([R, G, B])
这段代码使用OpenCV的 cv2.merge() 函数将拆分的通道重新合并为一幅彩色图像。这个新的图像 merged 包含了红色、绿色和蓝色通道。

显示和保存通道:

show(merged)
cv2.imshow(‘R’, R)
cv2.imshow(‘G’, G)
cv2.imshow(‘B’, B)
这部分代码将合并后的彩色图像 merged 显示在Matplotlib中,而红色通道(R)、绿色通道(G)和蓝色通道(B)分别使用OpenCV的 cv2.imshow() 显示。最后,cv2.waitKey(0) 等待用户按键,然后 cv2.destroyAllWindows() 用于关闭窗口。

在代码中,将分离的RGB通道分别用 cv2.imshow() 显示是正确的,但由于 cv2.imshow() 默认将单通道图像显示为灰度图像,所以三个通道都以灰度形式显示。

如果你希望以彩色方式显示这些通道,你可以使用以下方法:


#显示通道
cv2.imshow('R', cv2.cvtColor(R, cv2.COLOR_GRAY2BGR))
cv2.imshow('G', cv2.cvtColor(G, cv2.COLOR_GRAY2BGR))
cv2.imshow('B', cv2.cvtColor(B, cv2.COLOR_GRAY2BGR))

这将使用 cv2.cvtColor() 将每个单通道图像转换为BGR(彩色)图像,然后将其以彩色形式显示。然后,你将看到以彩色形式显示的三个通道,而不是灰度图像。

图像金字塔

图像金字塔是一种用于多尺度图像处理的技术。它的目标是在不同尺度上分析图像,使图像的不同特征在不同尺度下都能被捕捉到。图像金字塔通常用于计算机视觉任务,如目标检测、特征匹配、图像融合等。

图像金字塔主要有两种类型:高斯金字塔和拉普拉斯金字塔。

高斯金字塔:
高斯金字塔是通过不断降采样(缩小尺寸)原始图像而生成的金字塔。降采样是通过应用高斯滤波器进行模糊处理,然后采样得到较小的图像。高斯金字塔的每一层都比前一层更模糊,更小。高斯金字塔用于图像缩小和图像金字塔的构建。

拉普拉斯金字塔:
拉普拉斯金字塔是由高斯金字塔生成的。每一层的拉普拉斯金字塔包含了该层的图像和前一层的图像之间的差异(细节信息)。这种金字塔用于图像放大和图像融合。

应用和用途:

尺度不变性特征变换(SIFT):图像金字塔用于检测和描述图像中的关键点,以便进行特征匹配。
目标检测:在不同尺度上搜索目标物体。
图像融合:将不同尺度的图像合成为一个。
图像金字塔分类:使用金字塔图像数据进行分类。
通过使用图像金字塔,可以处理不同尺度、不同分辨率的图像,以实现更鲁棒的计算机视觉任务。金字塔技术在图像处理和计算机视觉中发挥着重要的作用。

图像金字塔
一般情况下,我们要处理是一副具有固定分辨率的图像。但是有些情况下,我们需要对同一图像的不同分辨率的子图像进行处理。比如,我们要在一幅图像中查找某个目标,比如脸,我们不知道目标在图像中的尺寸大小。这种情况下,我们需要创建创建一组图像,这些图像是具有不同分辨率的原始图像。我们把这组图像叫做图像金字塔(简单来说就是同一图像的不同分辨率的子图集合)。如果我们把最大的图像放在底部,最小的放在顶部,看起来像一座金字塔,故而得名图像金字塔。
在这里插入图片描述

高斯金字塔
高斯金字塔的顶部是通过将底部图像中的连续的行和列去除得到的。顶部图像中的每个像素值等于下一层图像中 5 个像素的高斯加权平均值。这样操作一次一个 MxN 的图像就变成了一个 M/2×N/2 的图像。所以这幅图像的面积就变为原来图像面积的四分之一。连续进行这样的操作我们就会得到一个分辨率不断下降的图像金字塔。我们可以使用函数cv2.pyrDown() 和 cv2.pyrUp() 构建图像金字塔。

拉普拉斯金字塔
拉普拉斯金字塔可以由高斯金字塔计算得来,公式如下:
在这里插入图片描述

import cv2
import matplotlib.pyplot as plt
import numpy as np


def show(image):
    plt.imshow(image)
    plt.axis('off')
    plt.show()


def imread(image):
    image = cv2.imread(image)
    image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
    return image


image = imread('image.jpg')
show(image)
print(image.shape)

for i in range(4):
    image = cv2.pyrDown(image)
    print(image.shape)
    show(image)

for i in range(4):
    image = cv2.pyrUp(image)
    print(image.shape)
    show(image)


#拉普拉斯金字塔
image = imread('image.jpg')
print("拉普拉斯金字塔",image.shape)
down_image1 = cv2.pyrDown(image)
print("拉普拉斯金字塔",down_image1.shape)
down_image2 = cv2.pyrUp(down_image1)

print("拉普拉斯金字塔",down_image2.shape)
up_image = cv2.pyrUp(down_image2)
print("拉普拉斯金字塔",up_image.shape)

#你在计算 laplacian 时出现了维度不匹配的错误,
#因为 down_image1 和 up_image 的维度不同。拉普拉斯金字塔的构建需要保持金字塔层次的一致性。
# 调整 up_image 的尺寸以匹配 down_image1
up_image = cv2.resize(up_image, (down_image1.shape[1], down_image1.shape[0]))

laplacian = down_image1-up_image
show(laplacian)



拉普拉斯金字塔输出
在这里插入图片描述

这段代码演示了如何构建高斯金字塔和拉普拉斯金字塔,以及如何对图像进行向下采样和向上采样。以下是代码的主要部分和操作:

加载图像:

python
Copy code
image = imread(‘image.jpg’)
这部分代码加载名为 ‘image.jpg’ 的彩色图像并使用 cv2.cvtColor 将其转换为RGB格式,然后使用 show 函数显示图像。

高斯金字塔:

首先,通过 cv2.pyrDown() 函数将图像向下采样,即缩小一倍,并使用 show 函数显示结果。
接着,继续向下采样,每次缩小一倍,共进行了4次。在每次迭代中,图像的大小减半,并使用 show 函数显示结果。
随后,使用 cv2.pyrUp() 函数对图像进行向上采样,即放大一倍,然后通过 cv2.resize 调整尺寸以匹配前一层的图像大小。向上采样也进行了4次,每次将图像的大小翻倍,然后使用 show 函数显示结果。
拉普拉斯金字塔:

首先,通过 cv2.pyrDown() 将原始图像进行向下采样,然后使用 cv2.pyrUp() 将下采样后的图像向上采样,最后调整尺寸以匹配原始图像的大小。
通过将原始图像减去经过调整后的向上采样图像,可以得到拉普拉斯金字塔的一层(包含高频细节)。
最后,使用 show 函数显示拉普拉斯金字塔的一层图像。
这段代码演示了高斯金字塔和拉普拉斯金字塔的构建,以及向下采样和向上采样的效果。高斯金字塔用于图像缩小,而拉普拉斯金字塔用于细节提取和图像放大。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值