一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

使用Python從2D圖像進行3D重建過程詳解

新機器視覺 ? 來源:新機器視覺 ? 2023-12-05 14:07 ? 次閱讀

2D圖像的三維重建是從一組2D圖像中創(chuàng)建對象或場景的三維模型的過程。這個技術廣泛應用于計算機視覺機器人技術和虛擬現(xiàn)實等領域。

在本文中,我們將解釋如何使用Python執(zhí)行從2D圖像到三維重建的過程。我們將使用TempleRing數(shù)據集作為示例,逐步演示這個過程。該數(shù)據集包含了在對象周圍的一個環(huán)上采樣的阿格里真托(Agrigento)“Dioskouroi神廟”復制品的47個視圖。

三維重建的關鍵概念

在深入了解如何使用Python從2D圖像執(zhí)行三維重建的詳細步驟之前,讓我們首先回顧一些與這個主題相關的關鍵概念。

深度圖

深度圖是一幅圖像,其中每個像素代表攝像機和場景中相應點之間的距離。深度圖常用于計算機視覺和機器人技術中,用于表示場景的三維結構。

有許多不同的方法可以從2D圖像計算深度圖,包括立體對應、結構光和飛行時間等。在本文中,我們將使用立體對應來從示例數(shù)據集計算深度圖。

Point Cloud

點云是表示對象或場景形狀的三維空間中的一組點。點云常用于計算機視覺和機器人技術中,用于表示場景的三維結構。

一旦我們計算出代表場景深度的深度圖,我們可以使用它來計算一個三維點云。這涉及使用有關攝像機內部和外部參數(shù)的信息,將深度圖中的每個像素投影回三維空間。

網格

網格是一個由頂點、邊和面連接而成的表面表示。網格常用于計算機圖形學和虛擬現(xiàn)實中,用于表示對象或場景的形狀。

一旦我們計算出代表對象或場景形狀的三維點云,我們可以使用它來生成一個網格。這涉及使用諸如Marching Cubes或Poisson表面重建等算法,將表面擬合到點云上。

逐步實現(xiàn)

現(xiàn)在我們已經回顧了與2D圖像的三維重建相關的一些關鍵概念,讓我們看看如何使用Python執(zhí)行這個過程。我們將使用TempleRing數(shù)據集作為示例,逐步演示這個過程。下面是一個執(zhí)行Temple Ring數(shù)據集中圖像的三維重建的示例代碼:

安裝庫:

pip install numpy scipy

導入庫:

#importing libraries 
import cv2
import numpy as np
import matplotlib.pyplot as plt
import os

加載TempleRing數(shù)據集的圖像:

# Directory containing the dataset images
dataset_dir = '/content/drive/MyDrive/templeRing'
# Initialize the list to store images
images = []# Attempt to load the grayscale images and store them in the list
for i in range(1, 48):  # Assuming images are named templeR0001.png to templeR0047.png
    img_path = os.path.join(dataset_dir, f'templeR{i:04d}.png')
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    if img is not None:
        images.append(img)
    else:
        print(f"Warning: Unable to load 'templeR{i:04d}.png'")# Visualize the input images
num_rows = 5  # Specify the number of rows
num_cols = 10  # Specify the number of columns
fig, axs = plt.subplots(num_rows, num_cols, figsize=(15, 8))# Loop through the images and display them
for i, img in enumerate(images):
    row_index = i // num_cols  # Calculate the row index for the subplot
    col_index = i % num_cols   # Calculate the column index for the subplot
    axs[row_index, col_index].imshow(img, cmap='gray')
    axs[row_index, col_index].axis('off')# Fill any remaining empty subplots with a white background
for i in range(len(images), num_rows * num_cols):
    row_index = i // num_cols
    col_index = i % num_cols
    axs[row_index, col_index].axis('off')plt.show()

d983037c-9322-11ee-939d-92fbcf53809c.jpg

解釋:這段代碼加載灰度圖像序列,將它們排列在網格布局中,并使用matplotlib顯示它們。

為每個圖像計算深度圖:

# Directory containing the dataset images
dataset_dir = '/content/drive/MyDrive/templeRing'
# Initialize the list to store images
images = []# Attempt to load the grayscale images and store them in the list
for i in range(1, 48):  # Assuming images are named templeR0001.png to templeR0047.png
    img_path = os.path.join(dataset_dir, f'templeR{i:04d}.png')
    img = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)
    if img is not None:
        images.append(img)
    else:
        print(f"Warning: Unable to load 'templeR{i:04d}.png'")# Initialize the list to store depth maps
depth_maps = []# Create a StereoBM object with your preferred parameters
stereo = cv2.StereoBM_create(numDisparities=16, blockSize=15)# Loop through the images to calculate depth maps
for img in images:
    # Compute the depth map
    disparity = stereo.compute(img, img)    # Normalize the disparity map for visualization
    disparity_normalized = cv2.normalize(
        disparity, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)    # Append the normalized disparity map to the list of depth maps
    depth_maps.append(disparity_normalized)# Visualize all the depth maps
num_rows = 5  # Specify the number of rows
num_cols = 10  # Specify the number of columns
fig, axs = plt.subplots(num_rows, num_cols, figsize=(15, 8))for i, depth_map in enumerate(depth_maps):
    row_index = i // num_cols  # Calculate the row index for the subplot
    col_index = i % num_cols   # Calculate the column index for the subplot
    axs[row_index, col_index].imshow(depth_map, cmap='jet')
    axs[row_index, col_index].axis('off')# Fill any remaining empty subplots with a white background
for i in range(len(depth_maps), num_rows * num_cols):
    row_index = i // num_cols
    col_index = i % num_cols
    axs[row_index, col_index].axis('off')plt.show()

解釋:這段代碼負責使用Stereo Block Matching(StereoBM)算法從一系列立體圖像中計算深度圖。它遍歷灰度立體圖像列表,并為每一對相鄰圖像計算深度圖。

可視化每個圖像的深度圖:

# Initialize an accumulator for the sum of depth maps
sum_depth_map = np.zeros_like(depth_maps[0], dtype=np.float64)
# Compute the sum of all depth maps
for depth_map in depth_maps:
    sum_depth_map += depth_map.astype(np.float64)
# Calculate the mean depth map by dividing the sum by the number of depth maps
mean_depth_map = (sum_depth_map / len(depth_maps)).astype(np.uint8)
# Display the mean depth map
plt.figure(figsize=(8, 6))
plt.imshow(mean_depth_map, cmap='jet')
plt.title('Mean Depth Map')
plt.axis('off')
plt.show()

輸出:

d9a56e80-9322-11ee-939d-92fbcf53809c.jpg

解釋:這段代碼通過累加深度圖來計算平均深度圖。然后,通過將總和除以深度圖的數(shù)量來計算平均值。最后,使用jet顏色圖譜顯示平均深度圖以進行可視化。

從平均深度圖計算三維點云

# Initialize an accumulator for the sum of depth maps
sum_depth_map=np.zeros_like(depth_maps[0],dtype=np.float64)

# Compute the sum of all depth maps
for depth_map in depth_maps:
    sum_depth_map += depth_map.astype(np.float64)# Calculate the mean depth map by dividing the sum by the number of depth maps
mean_depth_map = (sum_depth_map / len(depth_maps)).astype(np.uint8)# Display the mean depth map
plt.figure(figsize=(8, 6))
plt.imshow(mean_depth_map, cmap='jet')
plt.title('Mean Depth Map')
plt.axis('off')
plt.show()

d9bcacee-9322-11ee-939d-92fbcf53809c.jpg

解釋:這段代碼通過對深度圖進行累加來計算平均深度圖。然后,通過將總和除以深度圖的數(shù)量來計算平均值。最后,使用Jet顏色映射來可視化顯示平均深度圖。

計算平均深度圖的三維點云

#converting into point cloud 
points_3D = cv2.reprojectImageTo3D(mean_depth_map.astype(np.float32), np.eye(4))

解釋:該代碼將包含點云中點的三維坐標,并且您可以使用這些坐標進行三維重建。

點云生成網格

安裝庫

!pip install numpy scipy

導入庫

#importing libraries 
from scipy.spatial import Delaunay
from skimage import measure
from skimage.measure import marching_cubes

生成網格

verts, faces, normals, values = measure.marching_cubes(points_3D)

解釋:該代碼將Marching Cubes算法應用于3D點云以生成網格。它返回定義結果3D網格的頂點、面、頂點法線和標量值。

可視化網格

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces)
plt.show()

輸出:

d9d67de0-9322-11ee-939d-92fbcf53809c.png

解釋:該代碼使用matplotlib可視化網格。它創(chuàng)建一個3D圖并使用ax.plot_trisurf方法將網格添加到其中。

這段代碼從Temple Ring數(shù)據集加載圖像,并使用塊匹配(block matching)進行每個圖像的深度圖計算,然后通過平均所有深度圖來計算平均深度圖,并使用它來計算每個像素的三維點云。最后,它使用Marching Cubes算法從點云生成網格并進行可視化。

結果比較

# importing the libraries
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

# Create a figure with two subplots
fig, axs = plt.subplots(1, 2, figsize=(10, 5))# Visualize the original image in the first subplot
axs[0].imshow(images[0], cmap='gray')
axs[0].axis('off')
axs[0].set_title('Original')# Visualize the reconstructed mesh in the second subplot
ax = fig.add_subplot(1, 2, 2, projection='3d')
ax.plot_trisurf(verts[:, 0], verts[:, 1], verts[:, 2], triangles=faces)
ax.set_title('Reconstructed')# Show the figure
plt.show()

d9ed39c2-9322-11ee-939d-92fbcf53809c.jpg

解釋:在此代碼中,使用matplotlib創(chuàng)建了包含兩個子圖的圖形。在第一個圖中,顯示了來自數(shù)據集的原始圖像。在第二個圖中,使用3D三角形表面圖可視化了重建的3D網格。

方法2

以下是執(zhí)行來自TempleRing數(shù)據集圖像的3D重建的另一個示例代碼:

引入模塊:

import cv2
import numpy as np
import matplotlib.pyplot as plt
from google.colab.patches import cv2_imshow

加載兩個Temple Ring數(shù)據集圖像:

# Load the PNG images (replace with your actual file paths)
image1 = cv2.imread('/content/drive/MyDrive/templeRing/templeR0001.png')
image2 = cv2.imread('/content/drive/MyDrive/templeRing/templeR0002.png'

解釋:該代碼使用OpenCV的cv2.imread函數(shù)從TempleRing數(shù)據集加載兩個圖像。

轉換為灰度圖:

# Convert images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

該代碼使用OpenCV將兩個圖像轉換為灰度圖像。它們以單通道表示,其中每個像素的值表示其強度,并且沒有顏色通道。

查找SIFT關鍵點和描述符:

# Initialize the SIFT detector
sift = cv2.SIFT_create()

# Detect keypoints and compute descriptors for both images
kp1, des1 = sift.detectAndCompute(gray1, None)
kp2, des2 = sift.detectAndCompute(gray2, None)

該代碼使用尺度不變特征變換(SIFT)算法在兩個圖像中查找關鍵點和描述符。它使用OpenCV的cv2.SIFT_create()函數(shù)創(chuàng)建一個SIFT對象,并調用其detectAndCompute方法來計算關鍵點和描述符。

使用FLANN匹配器匹配描述符:

# Create a FLANN-based Matcher object
flann = cv2.FlannBasedMatcher({'algorithm': 0, 'trees': 5}, {})

# Match the descriptors using KNN (k-nearest neighbors)
matches = flann.knnMatch(des1, des2, k=2)

解釋:該代碼使用Fast Library for Approximate Nearest Neighbors(FLANN)匹配器對描述符進行匹配。它使用OpenCV的cv2.FlannBasedMatcher函數(shù)創(chuàng)建FLANN匹配器對象,并調用其knnMatch方法來找到每個描述符的k個最近鄰。

使用Lowe的比率測試篩選出好的匹配項

# Apply Lowe's ratio test to select good matches
good_matches = []
for m, n in matches:
    if m.distance < 0.7 * n.distance:
        good_matches.append(m)

解釋:該代碼使用Lowe的比率測試篩選出好的匹配項。它使用最近鄰和次近鄰之間距離比的閾值來確定匹配是否良好。

提取匹配的關鍵點

# Extract matched keypoints
src_pts = np.float32(
    [kp1[m.queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
dst_pts = np.float32(
    [kp2[m.trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)

解釋:該代碼從兩組關鍵點中提取匹配的關鍵點,這些關鍵點將用于估算對齊兩個圖像的變換。這些關鍵點的坐標存儲在'src_pts'和'dst_pts'中。

使用RANSAC找到單應矩陣

# Find the homography matrix using RANSAC
H, _ = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)

在這段代碼中,它使用RANSAC算法基于匹配的關鍵點計算描述兩個圖像之間的變換的單應矩陣。單應矩陣后來可以用于拉伸或變換一個圖像,使其與另一個圖像對齊。

使用單應矩陣將第一個圖像進行變換

# Perform perspective transformation to warp image1 onto image2
height, width = image2.shape[:2]
result = cv2.warpPerspective(image1, H, (width, height))
# Display the result
cv2_imshow(result)

解釋:該代碼使用單應矩陣和OpenCV的cv2.warpPerspective函數(shù)將第一個圖像進行變換。它指定輸出圖像的大小足夠大,可以容納兩個圖像,然后呈現(xiàn)結果圖像。

顯示原始圖像和重建圖像

# Display the original images and the reconstructed image side by side
fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(12, 4))
ax1.imshow(cv2.cvtColor(image1, cv2.COLOR_BGR2RGB))
ax1.set_title('Image 1')
ax1.axis('off')
ax2.imshow(cv2.cvtColor(image2, cv2.COLOR_BGR2RGB))
ax2.set_title('Image 2')
ax2.axis('off')
ax3.imshow(cv2.cvtColor(result, cv2.COLOR_BGR2RGB))
ax3.set_title('Reconstructed Image')
ax3.axis('off')
plt.show()

輸出:

解釋:這段代碼展示了在一個具有三個子圖的單一圖形中可視化原始圖像和重建圖像的過程。它使用matplotlib庫顯示圖像,并為每個子圖設置標題和軸屬性。

不同的可能方法

有許多不同的方法和算法可用于從2D圖像執(zhí)行3D重建。選擇的方法取決于諸如輸入圖像的質量、攝像機校準信息的可用性以及重建的期望準確性和速度等因素。

一些常見的從2D圖像執(zhí)行3D重建的方法包括立體對應、運動結構和多視圖立體。每種方法都有其優(yōu)點和缺點,對于特定應用來說,最佳方法取決于具體的要求和約束。

結論

總的來說,本文概述了使用Python從2D圖像進行3D重建的過程。我們討論了深度圖、點云和網格等關鍵概念,并使用TempleRing數(shù)據集演示了使用兩種不同方法逐步進行的過程。我們希望本文能幫助您更好地理解從2D圖像進行3D重建以及如何使用Python實現(xiàn)這一過程。有許多可用于執(zhí)行3D重建的不同方法和算法,我們鼓勵您進行實驗和探索,以找到最適合您需求的方法。

審核編輯:黃飛

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 機器人
    +關注

    關注

    212

    文章

    29280

    瀏覽量

    210874
  • 攝像機
    +關注

    關注

    3

    文章

    1672

    瀏覽量

    60898
  • 計算機視覺
    +關注

    關注

    9

    文章

    1705

    瀏覽量

    46474
  • 三維重建
    +關注

    關注

    0

    文章

    26

    瀏覽量

    10030
  • python
    +關注

    關注

    56

    文章

    4822

    瀏覽量

    85855

原文標題:使用Python進行二維圖像的三維重建

文章出處:【微信號:vision263com,微信公眾號:新機器視覺】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    如何同時獲取2d圖像序列和相應的3d點云?

    如何同時獲取2d圖像序列和相應的3d點云?以上來自于谷歌翻譯以下為原文How to obtain the sequence of 2d image and corresponding
    發(fā)表于 11-13 11:25

    PYNQ框架下如何快速完成3D數(shù)據重建

    3D可視化,作者創(chuàng)建了自己的3D2D可視化算法。這對于視頻輸入來說足夠快了,我們通過移動輸出模型來證明這一點。接下來,在PYNQ-Z2板上重新創(chuàng)建這個管道。我們在立體
    發(fā)表于 01-07 17:25

    2D3D視頻自動轉換系統(tǒng)

    研究和實現(xiàn)了一個基于OMAP3530的2D3D視頻自動轉換系統(tǒng),重點研究深度圖獲取和深度信息渲染等主要核心技術及其實現(xiàn)。該系統(tǒng)利用OMAP3530其特有的雙核結構,進行系統(tǒng)優(yōu)化:由其ARM處理器
    發(fā)表于 03-06 14:20 ?1次下載
    <b class='flag-5'>2D</b>到<b class='flag-5'>3D</b>視頻自動轉換系統(tǒng)

    適用于顯示屏的2D多點觸摸與3D手勢模塊

    本視頻將展示結合多點觸摸與3D手勢模塊的Microchip顯示解決方案。支持2D/3D功能的顯示屏是Microchip基于GestIC?技術的最新解決方案。顯示屏上結合了3D手勢與
    的頭像 發(fā)表于 06-06 02:45 ?5331次閱讀

    如何把OpenGL中3D坐標轉換成2D坐標

    在OpenGL中,一切事物都在3D空間中,但我們的屏幕坐標確實2D像素數(shù)組,OpenGL大部分工作就是把3D坐標轉換成適應屏幕的2D像素。3D
    的頭像 發(fā)表于 07-09 10:40 ?8747次閱讀

    人工智能系統(tǒng)VON,生成最逼真3D圖像

    研究團隊寫道:“我們的關鍵思想是將圖像生成過程分解為三個要素:形狀、視角和紋理,這種分離的3D表示方式使我們能夠在對抗學習框架下3D
    的頭像 發(fā)表于 12-07 09:28 ?7968次閱讀

    微軟新AI框架可在2D圖像上生成3D圖像

    已經有不少機構在將 2D 圖像轉換為 3D 形式的方面進行了嘗試,包括 Facebook、Nvidia 等公司的 AI 研究實驗室,或是類似 Threedy.AI 這樣的初創(chuàng)公司。
    的頭像 發(fā)表于 03-07 14:23 ?3201次閱讀

    阿里研發(fā)全新3D AI算法,2D圖片搜出3D模型

    AI技術的研究正在從2D走向更高難度的3D。12月3日,記者獲悉,阿里技術團隊研發(fā)了全新3D AI算法,可基于2D圖片精準搜索出相應的
    的頭像 發(fā)表于 12-04 15:49 ?3793次閱讀

    谷歌發(fā)明的由2D圖像生成3D圖像技術解析

    谷歌發(fā)明的由2D圖像生成3D圖像的技術,利用3D估計神經網絡圖像信息的補全以及預測,融合了拍攝角
    的頭像 發(fā)表于 12-24 12:55 ?4966次閱讀
    谷歌發(fā)明的由<b class='flag-5'>2D</b><b class='flag-5'>圖像</b>生成<b class='flag-5'>3D</b><b class='flag-5'>圖像</b>技術解析

    3d人臉識別和2d人臉識別的區(qū)別

    首先是3d人臉識別和2d人臉識別圖像數(shù)據獲取不同。3D人臉識別是以3D攝像頭立體成像,而2D是以
    發(fā)表于 02-05 16:00 ?5w次閱讀

    如何直接建立2D圖像中的像素和3D點云中的點之間的對應關系

    準確描述和檢測 2D3D 關鍵點對于建立跨圖像和點云的對應關系至關重要。盡管已經提出了大量基于學習的 2D3D 局部特征描述符和
    的頭像 發(fā)表于 10-18 09:20 ?9622次閱讀

    2D3D視覺技術的比較

    作為一個多年經驗的機器視覺工程師,我將詳細介紹2D3D視覺技術的不同特點、應用場景以及它們能夠解決的問題。在這個領域內,2D3D視覺技術是實現(xiàn)自動化和智能制造的關鍵技術,它們在工業(yè)
    的頭像 發(fā)表于 12-21 09:19 ?1592次閱讀

    一文了解3D視覺和2D視覺的區(qū)別

    一文了解3D視覺和2D視覺的區(qū)別 3D視覺和2D視覺是兩種不同的視覺模式,其區(qū)別主要體現(xiàn)在立體感、深度感和逼真度上。本文將詳細闡述這些區(qū)別,并解釋為什么
    的頭像 發(fā)表于 12-25 11:15 ?4118次閱讀

    介紹一種使用2D材料進行3D集成的新方法

    美國賓夕法尼亞州立大學的研究人員展示了一種使用2D材料進行3D集成的新穎方法。
    的頭像 發(fā)表于 01-13 11:37 ?1273次閱讀

    AN-1249:使用ADV8003評估板將3D圖像轉換成2D圖像

    電子發(fā)燒友網站提供《AN-1249:使用ADV8003評估板將3D圖像轉換成2D圖像.pdf》資料免費下載
    發(fā)表于 01-08 14:28 ?0次下載
    AN-1249:使用ADV8003評估板將<b class='flag-5'>3D</b><b class='flag-5'>圖像</b>轉換成<b class='flag-5'>2D</b><b class='flag-5'>圖像</b>