基于机器学习的视觉应用, 又名:机器视觉之从调包侠到底层开发(第3天)
PS:这个系列是准备做从Python一些接口应用开发,openCV基础使用场景原理讲解,做一些demo案例讲解,然后开始数学基础复习, 基础图像处理技术概念, 特征提取和描述细节, 深入了解图像分割和识别,三维视觉和摄影测量,和用C++进行图形学上的练习,再抽几篇关键的前沿文献和教材阅读。企业级项目制作。 最后再进行图像方向的论文写作让研究生阶段就可以发表的文献。
需要对理论进行补充, 包括:数学基础复习, 基础图像处理技术, 三维视觉和摄影测量, 图形学, 机器学习
import cv2
# 读取图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
# 高斯滤波
image_blurred = cv2.GaussianBlur(image, (5, 5), 0)
# 计算梯度
gradient_x = cv2.Sobel(image_blurred, cv2.CV_64F, 1, 0, ksize=3)
gradient_y = cv2.Sobel(image_blurred, cv2.CV_64F, 0, 1, ksize=3)
# 计算梯度幅值和方向
gradient_magnitude = cv2.magnitude(gradient_x, gradient_y)
gradient_direction = cv2.phase(gradient_x, gradient_y)
# 非极大值抑制
gradient_magnitude_suppressed = cv2.morphologyEx(gradient_magnitude, cv2.MORPH_CLOSE, None)
# 双阈值边缘跟踪
low_threshold = 50
high_threshold = 150
edges = cv2.Canny(gradient_magnitude_suppressed, low_threshold, high_threshold)
# 显示边缘图像
cv2.imshow('Canny Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
# 读取图像
image = cv2.imread('object.jpg')
# 转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# 二值化
ret, binary_image = cv2.threshold(gray_image, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(binary_image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# 绘制轮廓
cv2.drawContours(image, contours, -1, (0,
255, 0), 2)
# 显示带有轮廓的图像
cv2.imshow('Object Contours', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
import numpy as np
# 读取图像
image = cv2.imread('corners.jpg', cv2.IMREAD_GRAYSCALE)
# Harris角点检测参数
block_size = 2
aperture_size = 3
k = 0.04
# 检测角点
corners = cv2.cornerHarris(image, block_size, aperture_size, k)
# 标记角点
image[corners > 0.01 * corners.max()] = [0, 0, 255]
# 显示带有角点标记的图像
cv2.imshow('Harris Corners', image)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像梯度和非极大值抑制是特征检测中常用的技术和方法。
特征检测是通过分析图像中的局部特征来识别和描述图像中的对象或兴趣点。图像梯度和非极大值抑制可以帮助我们在图像中找到边缘和细线条等特征,从而用于特征检测。
在特征检测中,我们通常会使用图像梯度计算算子来寻找边缘和细线条,然后应用非极大值抑制来提取出具有最大梯度值的像素作为特征点。
滞后阈值是一种在图像处理中常用的技术,用于处理噪声或者增强图像的特定部分。滞后阈值的目的是通过对像素值进行比较和阈值化来提取感兴趣的特征或区域。
滞后阈值的算法步骤如下:
滞后阈值的目的是通过选择合适的阈值来提取图像中的边缘或特定的目标。通过调整高阈值和低阈值的值,可以控制提取边缘的数量和质量。
注意:滞后阈值算法中的阈值选择是非常重要的,不同的阈值选择可能会导致不同的边缘提取结果。通常,根据具体的应用需求和图像特点来选择适当的阈值。
边缘检测是图像处理中一种常用的技术,用于检测图像中的边缘或轮廓。边缘通常是图像中亮度变化较大的区域,表示物体的边界或纹理变化。边缘检测的目的是找到图像中的边缘,并将其提取出来。
常用的边缘检测算法包括Sobel算子、Canny边缘检测和Laplacian算子等。
轮廓检测是一种用于检测图像中物体边界的技术。轮廓是由一系列连续的点组成的曲线,表示物体的外形。轮廓检测的目的是找到图像中的物体轮廓,并将其提取出来。
常用的轮廓检测算法包括边缘检测和连通组件标记等。
轮廓检测可以应用于物体识别、物体测量、图像分割等领域。通过检测图像中的轮廓,可以获取物体的形状和边界信息,从而进行进一步的分析和处理。
以上是边缘检测和轮廓检测的原理和常用算法的概述。
FAST(Features from Accelerated Segment Test)算法是一种用于检测图像中关键点的快速算法。它通过在图像的像素周围进行像素值比较,来确定是否存在关键点。FAST算法的特点是速度快,适用于实时图像处理。
使用场景: FAST算法通常用于图像特征检测,例如在目标跟踪、图像拼接和物体识别中。
算法解释: FAST算法选择一个像素作为中心点,并将其周围的16个像素分成4个方向,分别为东、南、西、北。然后,它通过比较中心像素的亮度与相邻像素的亮度来判断是否为关键点。如果中心像素比相邻像素的亮度高或低,且连续的12个像素中至少有3个像素亮度高或低,则将中心像素标记为关键点。
BRIEF(Binary Robust Independent Elementary Features)算法用于描述关键点的特征。它采用二进制描述符,可以高效地匹配关键点。
使用场景: BRIEF算法通常用于特征匹配,例如在图像配准、物体识别和图像拼接中。
算法解释: BRIEF算法首先选择一组随机的像素对,然后比较这些像素对的亮度。根据像素对的比较结果,生成一个二进制字符串作为关键点的描述符。这个描述符可以高效地进行匹配,因为它只包含了像素对的二进制比较结果。
特征匹配是将两个图像中的关键点进行对应的过程。在ORB算法中,通常使用汉明距离(Hamming Distance)来衡量两个关键点描述符的相似性。较小的汉明距离表示描述符越相似,从而进行匹配。
以下是使用ORB特征和暴力匹配、FLANN匹配进行特征匹配的简化代码流程:
import cv2
# 加载图像
img1 = cv2.imread('image1.jpg', cv2.IMREAD_GRAYSCALE)
img2 = cv2.imread('image2.jpg', cv2.IMREAD_GRAYSCALE)
# 创建ORB检测器
orb = cv2.ORB_create()
# 检测关键点和描述符
keypoints1, descriptors1 = orb.detectAndCompute(img1, None)
keypoints2, descriptors2 = orb.detectAndCompute(img2, None)
# 创建暴力匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 使用暴力匹配器进行特征匹配
matches_bf = bf.match(descriptors1, descriptors2)
# 根据匹配距离排序匹配结果
matches_bf = sorted(matches_bf, key=lambda x: x.distance)
# 创建FLANN匹配器
index_params = dict(algorithm=0, trees=5)
search_params = dict(checks=50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
# 使用FLANN匹配器进行特征匹配
matches_flann = flann.knnMatch(descriptors1, descriptors2, k=2)
# 根据匹配距离和比率筛选匹配结果
good_matches_flann = []
for m, n in matches_flann:
if m.distance < 0.7 * n.distance:
good_matches_flann.append(m)
# 显示匹配结果
img_matches_bf = cv2.drawMatches(img1, keypoints1, img2, keypoints2, matches_bf[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
img_matches_flann = cv2.drawMatches(img1, keypoints1, img2, keypoints2, good_matches_flann[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
cv2.imshow('Brute-Force Matches', img_matches_bf)
cv2.imshow('FLANN Matches', img_matches_flann)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上代码演示了如何使用ORB特征检测器和暴力匹配、FLANN匹配进行特征匹配,并绘制匹配结果。
图像拼接是将多张图像合并成一张大图像的过程。要学习图像拼接,您需要掌握以下知识点:
概念介绍: 单应性矩阵是一种描述两个平面之间映射关系的矩阵。在图像处理中,单应性矩阵常用于实现透视变换,将一个平面上的点映射到另一个平面上。
透视变换: 透视变换是一种图像变换技术,可以将一个平面上的图像映射到另一个平面上,同时保持图像的形状和几何关系不变。透视变换通过应用单应性矩阵来实现。
场景运用: 单应性矩阵与透视变换在图像拼接、全景摄影、虚拟现实、增强现实等领域具有重要应用。通过透视变换,可以将多张图像对齐到同一个坐标系下,实现图像的平移、旋转、缩放和畸变矫正等操作。
示例代码: 以下是使用OpenCV库进行透视变换的简化代码流程:
import cv2
import numpy as np
# 读取图像
image = cv2.imread('input_image.jpg')
# 定义原始图像上的四个点
original_points = np.float32([[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
# 定义目标图像上的四个点
target_points = np.float32([[x1, y1], [x2, y2], [x3, y3], [x4, y4]])
# 计算透视变换矩阵
perspective_matrix = cv2.getPerspectiveTransform(original_points, target_points)
# 进行透视变换
output_image = cv2.warpPerspective(image, perspective_matrix, (width, height))
# 显示结果图像
cv2.imshow('Output Image', output_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像融合是将多张图像合并为一张图像的过程,实现平滑过渡和无缝连接。图像融合的目的是将多个部分图像的信息整合到一起,形成一个更大、更完整的图像。
图像融合在许多领域都有应用,例如全景摄影、虚拟现实、医学影像和图像拼接等。通过图像融合,可以将多张图像无缝地拼接在一起,提供更广阔的视野和更丰富的信息。
以下是使用OpenCV库进行图像融合的简化代码流程:
import cv2
import numpy as np
# 读取图像
image1 = cv2.imread('image1.jpg')
image2 = cv2.imread('image2.jpg')
# 融合图像
alpha = 0.5 # 融合权重
blended_image = cv2.addWeighted(image1, alpha, image2, 1-alpha, 0)
# 显示融合结果
cv2.imshow('Blended Image', blended_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
以上代码演示了如何使用OpenCV库将两张图像进行简单的线性融合。通过调整融合权重alpha的值,可以控制两张图像在融合结果中的贡献程度,从而实现不同的融合效果。
全景图像拼接是将多张部分重叠的图像合并成一张全景图像的过程。它的原理是通过计算不同图像之间的变换关系,将它们对齐在同一个坐标系中。
使用场景: 全景图像拼接常用于全景摄影、虚拟现实、地图制作等领域。
全景图像拼接的一般步骤包括:
RANSAC(Random Sample Consensus)算法是用于估计数据中存在的模型的算法,它可以鲁棒地估计变换关系,适用于图像对齐和拼接。
算法解释: RANSAC算法通过随机选择数据中的样本来估计模型,然后根据估计的模型计算数据点与模型的拟合程度,并将符合拟合要求的数据点作为内点。然后,使用内点重新估计模型,直到达到一定的迭代次数或准确度要求。
全景图像拼接后,通常会包含一些多余的区域。全景图像剪裁是将全景图像裁剪为所需的大小,去除多余的部分。
以下是使用OpenCV进行全景图像拼接的简化代码流程:
import cv2
# 加载图像
img1 = cv2.imread('image1.jpg')
img2 = cv2.imread('image2.jpg')
# 创建SIFT检测器
sift = cv2.SIFT_create()
# 检测关键点和描述符
keypoints1, descriptors1 = sift.detectAndCompute(img1, None)
keypoints2, descriptors2 = sift.detectAndCompute(img2, None)
# 创建FLANN匹配器
flann = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': 5}, {})
# 使用匹配器进行特征匹配
matches = flann.knnMatch(descriptors1, descriptors2, k=2)
# 根据匹配距离和比率筛选匹配结果
good_matches = []
for m, n in matches:
if m.distance < 0.7 * n.distance:
good_matches.append(m)
# 估计变换关系
src_pts = np.float32([keypoints1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32([keypoints2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
M, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
# 图像拼接
result = cv2.warpPerspective(img1, M, (img1.shape[1] + img2.shape[1], img1.shape[0]))
result[0:img2.shape[0], 0:img2.shape[1]] = img2
# 显示拼接结果
cv2.imshow('Panorama', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
要实现戒指与图片的特征匹配,可以使用计算机视觉库,如OpenCV,结合特征检测和特征描述符匹配的技术。
以下是一个简化的Python示例代码,演示了如何使用ORB特征检测器和暴力匹配进行手表与图片的特征匹配:
import cv2
# 加载戒指图像和目标图像
watch_image = cv2.imread('rong.jpg', cv2.IMREAD_GRAYSCALE)
target_image = cv2.imread('target.jpg', cv2.IMREAD_GRAYSCALE)
# 创建ORB检测器
orb = cv2.ORB_create()
# 检测戒指图像和目标图像的关键点和描述符
keypoints_watch, descriptors_watch = orb.detectAndCompute(watch_image, None)
keypoints_target, descriptors_target = orb.detectAndCompute(target_image, None)
# 创建暴力匹配器
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
# 使用暴力匹配器进行特征匹配
matches = bf.match(descriptors_watch, descriptors_target)
# 根据匹配距离排序匹配结果
matches = sorted(matches, key=lambda x: x.distance)
# 绘制特征匹配结果
result_image = cv2.drawMatches(watch_image, keypoints_watch, target_image, keypoints_target, matches[:10], None, flags=cv2.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
# 显示匹配结果
cv2.imshow('Feature Matching Result', result_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
这段代码将手表图像和目标图像加载为灰度图像,并使用ORB特征检测器检测关键点和描述符。然后,使用暴力匹配器对手表图像和目标图像的特征描述符进行匹配,并根据匹配距离进行排序。最后,绘制出前10个特征匹配结果,并显示匹配结果。
注意:在实际应用中,可能需要根据具体的图像和场景进行参数调整和优化,以获得更好的特征匹配效果。