如何用opencv提取一张图片的像素矩阵

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用opencv提取一张图片的像素矩阵相关的知识,希望对你有一定的参考价值。

操作单个像素方法:
at(int y, int x)
cv::mat的成员函数: at(int y, int x)可以用来存取图像中对应坐标为(x,y)的元素坐标。但是在使用它时要注意,在编译期必须要已知图像的数据类型,这是因为cv::mat可以存放任意数据类型的元素。因此at方法的实现是用模板函数来实现的。
使用方法:假设提前已知一幅图像img的数据类型为 unsigned char型灰度图(单通道),要对坐标为(10,12)的像素重新赋值为128,则对应操作如下
img.at<uchar>(12,10) = 128;
参考技术A 矩阵是像素的集合,通道是指每个像素用几种基色(不知道这样描述准不准确)组成,一般由RGB组成,有的带有a(alpha)。可以用cvSplit函数将3/4通道的图像的追问

然后呢?

参考技术B 从imageData中取,BGR顺序存的,每WidthStep换行本回答被提问者采纳 参考技术C 矩阵是像素的集合,通道是指每个像素用几种基色(不知道这样描述准不准确)组成,一般由RGB组成,有的带有a(alpha)。可以用cvSplit函数将3/4通道的图像的RGB(假设是RGB颜色空间)分离成只有R的图片、只有G的图片和只有B的图片!

OpenCV 相机校正

1. 相机标定

根据张正友校正算法,利用棋盘格数据校正对车载相机进行校正,计算其内参矩阵,外参矩阵和畸变系数。

标定的流程是:

  • 准备棋盘格数据,即用于标定的图片
  • 对每一张图片提取角点信息
  • 在棋盘上绘制提取到的角点(非必须,只是为了显示结果)
  • 利用提取的角点对相机进行标定
  • 获取相机的参数信息

2.关于相机校正用到的几个API:

  1. 寻找棋盘图中的棋盘角点
rect, corners = cv2.findChessboardCorners(image, pattern_size, flags)

参数:

  • Image: 输入的棋盘图,必须是8位的灰度或者彩色图像

  • Pattern_size:棋盘图中每行每列的角点个数(内角点)。

  • flags: 用来定义额外的滤波步骤以有助于寻找棋盘角点。所有的变量都可以单独或者以逻辑或的方式组合使用。取值主要有:

    CV_CALIB_CB_ADAPTIVE_THRESH :使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。

    CV_CALIB_CB_NORMALIZE_IMAGE :在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。

    CV_CALIB_CB_FILTER_QUADS :使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

返回:

  • Corners:检测到的角点
  • rect: 输出是否找到角点,找到角点返回1,否则返回0
  1. 检测完角点之后可以将测到的角点绘制在图像上,使用的API是:

    cv2.drawChessboardCorners(img, pattern_size, corners, rect)
    

    参数:

    • Img: 预绘制检测角点的图像
    • pattern_size : 预绘制的角点的形状
    • corners: 角点矩阵
    • rect: 表示是否所有的棋盘角点被找到,可以设置为findChessboardCorners的返回值

    注意:如果发现了所有的角点,那么角点将用不同颜色绘制(每行使用单独的颜色绘制),并且把角点以一定顺序用线连接起来。

  2. 利用定标的结果计算内外参数

ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, image_size, None, None)

参数:

  • Object_points:世界坐标系中的点,在使用棋盘的场合,令z的坐标值为0,而x,y坐标用里面来度量,选用英寸单位,那么所有参数计算的结果也是用英寸表示。最简单的方式是定义棋盘的每一个方块为一个单位。
  • image_points:在图像中寻找到的角点的坐标,包含object_points所提供的所有点
  • image_size: 图像的大小,以像素为衡量单位

返回:

  • ret: 返回值

  • mtx: 相机的内参矩阵,大小为3*3的矩阵

  • dist: 畸变系数,为5*1大小的矢量

  • rvecs: 旋转变量

  • tvecs: 平移变量

2.1 图像去畸变

上一步中得到相机的内参及畸变系数,利用其进行图像的去畸变,最直接的方法就是调用opencv中的函数得到去畸变的图像:

def img_undistort(img, mtx, dist):
    dst = cv2.undistort(img, mtx, dist, None, mtx)
    return dst

求畸变的API:

dst = cv2.undistort(img, mtx, dist, None, mtx)

参数:

  • Img: 要进行校正的图像
  • mtx: 相机的内参
  • dist: 相机的畸变系数

返回:

  • dst: 图像校正后的结果

3. 相机校正

import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import glob

def plot_contrast_imgs(origin_img, converted_img, origin_img_title="origin_img", converted_img_title="converted_img", converted_img_gray=False):
    """
    用于对比显示两幅图像
    """
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 20))
    ax1.set_title(origin_img_title)
    ax1.imshow(origin_img)
    ax2.set_title(converted_img_title)
    if converted_img_gray==True:
        ax2.imshow(converted_img, cmap="gray")
    else:
        ax2.imshow(converted_img)
    plt.show()

# 1. 参数设定:定义棋盘横向和纵向的角点个数并指定校正图像的位置
nx = 9
ny = 6
file_paths = glob.glob("./camera_cal/calibration*.jpg")
# 2. 计算相机的内外参数及畸变系数
def cal_calibrate_params(file_paths):
    object_points = []  # 三维空间中的点:3D
    image_points = []   # 图像空间中的点:2d
    # 2.1 生成真实的交点坐标:类似(0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)的三维点
    objp = np.zeros((nx * ny, 3), np.float32)
    objp[:, :2] = np.mgrid[0:nx, 0:ny].T.reshape(-1, 2)
    # 2.2 检测每幅图像角点坐标
    for file_path in file_paths:
        img = cv2.imread(file_path)
        # 将图像转换为灰度图
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        # 自动检测棋盘格内4个棋盘格的角点(2白2黑的交点)
        rect, corners = cv2.findChessboardCorners(gray, (nx, ny), None)
        # 若检测到角点,则将其存储到object_points和image_points
        if rect == True:
            object_points.append(objp)
            image_points.append(corners)
    # 2.3 获取相机参数
    ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)
    return ret, mtx, dist, rvecs, tvecs


def img_undistort(img, mtx, dist):
    """
    图像去畸变
    """
    return cv2.undistort(img, mtx, dist, None, mtx)

# 测试去畸变函数的效果
file_paths = glob.glob("./camera_cal/calibration*.jpg")
ret, mtx, dist, rvecs, tvecs = cal_calibrate_params(file_paths)
if mtx.any() != None:  # a.any() or a.all()
    img = mpimg.imread("./camera_cal/calibration1.jpg")
    undistort_img = img_undistort(img, mtx, dist)
    plot_contrast_imgs(img, undistort_img)
    print("done!")
else:
    print("failed")

执行代码:
在这里插入图片描述

以上是关于如何用opencv提取一张图片的像素矩阵的主要内容,如果未能解决你的问题,请参考以下文章

android中如何用opencv处理倾斜校正的问题,求源代码

如何用Keras自定义层?

学习Opencv 2.4.9 ---操作像素

OpenCV 相机校正

如何用matlab计算出图片中的RGB3个矩阵

如何使用opencv获取已经灰度化二值化的一张黑色图片中的一个亮点的具体像素坐标