OpenCV机器视觉-图片操作原理

图片操作原理


之前描述过一张图片,在计算机程序中,其实是用矩阵来进行描述的,如果我们想对这张图片进行操作,其实就是要对矩阵进行运算。

下面列出常见的几种变换矩阵
在这里插入图片描述

接着来演示 的是图片的位移操作,将一个矩阵的列和行看成坐标系中的x和y就可以轻易的来操作矩阵。

import cv2
import numpy as np

img = cv2.imread('./timg.jpg', cv2.IMREAD_COLOR)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 创建一个和原图大小的矩阵
dstImg = np.zeros((height, width, 3), np.uint8)

for row in range(height):
    for col in range(width):
        # 补全齐次坐标
        sourceMatrix = np.array([col, row, 1])

        matrixB = np.array([[1, 0, 50],
                            [0, 1, 100]])
        # 矩阵相乘
        dstMatrix = matrixB.dot(sourceMatrix.T)
        # 从原图中获取数据
        dstCol = int(dstMatrix[0])
        dstRow = int(dstMatrix[1])
        # 防止角标越界
        if dstCol < width and dstRow < height:
            dstImg[dstRow, dstCol] = img[row, col]

# 显示图片
cv2.imshow('dstImg', dstImg)
cv2.waitKey(0)
cv2.destroyAllWindows()

图片移位


以上是采用纯手工的方式来操作图片,其实完全没有必要那样做,opencv中已经提供好了相关的计算机操作,我们只需要提供变换矩阵就好了。

cv.warpAffine(原始图像,变换矩阵,(高度,宽度))

下面是位移的示例代码:

import numpy as np

import cv2

img = cv2.imread('./timg.jpg', cv2.IMREAD_COLOR)
imInfo = img.shape
height = imInfo[0]
width = imInfo[1]

# 定义位移矩阵
matrixShift = np.float32([
    [1, 0, 50],
    [0, 1, 100]
])

# 调用api
dstImg = cv2.warpAffine(img, matrixShift, (width, height))

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

图片旋转


图片的旋转其实也是很简单的,只不过默认是以图片的左上角为旋转中心

示例代码:

import numpy as np

import cv2

img = cv2.imread('./jjy.jpg', cv2.IMREAD_COLOR)
imgInfo = img.shape
height = imgInfo[0]
width = imgInfo[1]

# 定义图片 左上角,左下角 右上角的坐标
matrixSrc = np.float32([[0, 0], [0, height - 1], [width - 1, 0]])
# 将原来的点映射到新的点
matrixDst = np.float32([[50, 100], [300, height - 200], [width - 300, 100]])
# 将俩个矩阵组合在一起,仿射变换矩阵
matrixAffine = cv2.getAffineTransform(matrixSrc, matrixDst)

dstImg = cv2.warpAffine(img, matrixAffine, (width, height))

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

图像金字塔


图像金字塔是图像多尺度表达的一种,是一种以多分辨率来解释图像的有效但概念简单的结构。一幅图像的金字塔是一系列以金字塔形状排列的分辨率逐步降低,且来源于同一张原始图的图像集合。其通过梯次向下采样获得,知达到某个条件终止才停止采样。我们将一层一层的图像比喻成金字塔,层级越高,则图像越小,分辨率越低。
在这里插入图片描述
降低图像的分辨率,我们可以称为下采样

提高图像的分辨率,我们可以称为上采样

下面来测试一下采用这样采样操作进行缩放和我们直接进行resize操作他们之间有什么差别。

我们可以看到,当我们对图片进行下采样操作的时候,即使图片变得非常小,我们任然能够看到它的轮廓,这是对机器学习操作是非常重要的。
在这里插入图片描述
实例代码:

import cv2 as cv

src_img = cv.imread("./timg.jpg", cv.IMREAD_COLOR);
imgInfo = src_img.shape
height = imgInfo[0]
width = imgInfo[1]

pry_down1 = cv.pyrDown(src_img)
cv.imshow("down1", pry_down1)
pry_down2 = cv.pyrDown(pry_down1)
cv.imshow("down2", pry_down2)
pry_down3 = cv.pyrDown(pry_down2)
cv.imshow("down3", pry_down3)
pry_down4 = cv.pyrDown(pry_down3)
cv.imshow("down4", pry_down4)

pyr_up1 = cv.pyrUp(pry_down1)
cv.imshow("up1", pyr_up1)
pyr_up2 = cv.pyrUp(pry_down2)
cv.imshow("up2", pyr_up2)
pyr_up3 = cv.pyrUp(pry_down3)
cv.imshow("up3", pyr_up3)
pyr_up4 = cv.pyrUp(pry_down4)
cv.imshow("up4", pyr_up4)

# 对比resize
img2 = cv.resize(src_img, (int(height / 2), int(width / 2)))
cv.imshow("img1/2", img2)

img4 = cv.resize(src_img, (int(height / 4), int(width / 4)))
cv.imshow("img1/4", img4)

img8 = cv.resize(src_img, (int(height / 8), int(width / 8)))
cv.imshow("img1/8", img8)

img16 = cv.resize(src_img, (int(height / 16), int(width / 16)))
cv.imshow("img1/16", img16)

cv.waitKey(0)
cv.destroyAllWindows()

猜你喜欢

转载自blog.csdn.net/weixin_45946270/article/details/124561526