跳转至

记录十一假期准备2023中国机器人大赛先进视觉专项赛

约 11389 个字 • 541 行代码

9.29

测试使用相机

这届比赛要求使用 奥比中光 Astra+ 型号相机

相关使用文档

奥比中光AI开放平台|全球首个聚焦3D视觉开放平台 (orbbec.com.cn)

Orbbec SDK for Python 使用手册

Windows python sdk 编译 中,“下载 python sdk 源码” 处的github仓库链接应该是写错了,我去github上面查找了一下,应该是这个

orbbec/pyorbbecsdk: OrbbecSDK python binding (github.com)

所以应该是

git clone https://github.com/orbbec/pyorbbecsdk.git

但装好sdk之后,还未找到如何使用深度摄像头的方法

处理算法相关

想要实现识别出桌面的算法,需要解决遮挡等问题(比如桌角和桌子边缘有可能会被遮挡)

霍夫变换的思路

与 Bing 的对话记录

chatlog

user:

Can you help me find some Python code to recognize and segment the edges of A4 paper using OpenCV

bing:

Certainly! I can help you with that. 😊

To recognize and segment the edges of an A4 paper using OpenCV, you can use the following Python code:

import cv2

# Load the image
image = cv2.imread('your_image.jpg')

# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Apply Canny edge detection to detect the edges
edges = cv2.Canny(gray, 100, 200)

# Perform further processing on the detected edges as per your requirements

# Display the result
cv2.imshow('Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

This code uses the Canny edge detection algorithm provided by OpenCV to detect the edges of an image. You can adjust the threshold values (100 and 200) in the cv2.Canny() function to fine-tune the edge detection based on your specific requirements¹.

Please note that this is a basic example, and you may need to perform additional steps to specifically recognize and segment the edges of an A4 paper. The exact approach may vary depending on factors such as lighting conditions, image quality, and other specific requirements.

Let me know if there's anything else I can assist you with!

Source: Conversation with Bing, 2023/9/29

  1. (1) OpenCV C++/Obj-C: Detecting a sheet of paper / Square Detection. https://stackoverflow.com/questions/8667818/opencv-c-obj-c-detecting-a-sheet-of-paper-square-detection.
  2. (2) . https://bing.com/search?q=Python+code+to+recognize+and+segment+the+edges+of+A4+paper+using+OpenCV.
  3. (3) Image Edge Detection in Python using OpenCV: Step-by-step - Codefather. https://codefather.tech/blog/image-edge-detection-python/.
  4. (4) How to find the document edges in various coloured backgrounds using .... https://stackoverflow.com/questions/55513477/how-to-find-the-document-edges-in-various-coloured-backgrounds-using-opencv-pyth.
  5. (5) Recognizing digits with OpenCV and Python - PyImageSearch. https://pyimagesearch.com/2017/02/13/recognizing-digits-with-opencv-and-python/.
  6. (6) undefined. https://dev.to/kalebu/how-to-detect-edges-in-an-image-using-opencv-in-python-12cm.
  7. (7) undefined. https://thepythoncode.com/article/canny-edge-detection-opencv-python.
  8. (8) undefined. https://learnopencv.com/edge-detection-using-opencv/.

user:

If all four corners of the paper are obstructed, how can we identify the paper by detecting its edges? Can you help me find answers to relevant questions or links to articles

bing:

If all four corners of the paper are obstructed, it becomes challenging to identify the paper by detecting its edges. However, you can still try to detect the edges using OpenCV by following these steps:

  1. Preprocessing: Apply image preprocessing techniques such as noise removal, image enhancement, or thresholding to improve the quality of the input image.

  2. Edge Detection: Use edge detection algorithms like Canny, Sobel, or Laplacian to detect edges in the preprocessed image. These algorithms can help identify sharp changes in pixel intensity, which often correspond to edges.

  3. Hough Transform: Apply the Hough Transform to detect lines or curves in the edge-detected image. The Hough Transform can help you find geometric shapes like lines or circles.

  4. Line Intersection: If you detect multiple lines using the Hough Transform, you can find their intersections to identify the corners of the paper. The intersection points represent the corners of the paper even if they are obstructed.

  5. Paper Segmentation: Once you have identified the corners of the paper, you can use them to segment the paper from the rest of the image. This segmentation can help isolate the A4 paper for further processing or analysis.

Please note that this approach assumes that at least some part of each corner is visible or detectable. If all four corners are completely obstructed, it may not be possible to accurately identify the paper using edge detection alone.

Feel free to experiment with these steps and adjust them based on your specific requirements and constraints. Good luck with your project! 🚀

Source: Conversation with Bing, 2023/9/29

  1. (1) Algorithm to detect corners of paper sheet in photo. https://stackoverflow.com/questions/6555629/algorithm-to-detect-corners-of-paper-sheet-in-photo.
  2. (2) Scanning Documents from Photos Using OpenCV - Breta Hajek. https://bretahajek.com/2017/01/scanning-documents-photos-opencv/.
  3. (3) OpenCV for detecting Edges, lines and shapes - Packt Hub. https://hub.packtpub.com/opencv-detecting-edges-lines-shapes/.
  4. (4) undefined. http://madteckhead.com/tmp.

user:

What is Hough transform? Can you give me a brief introduction

bing:

Certainly! The Hough Transform is a computer vision technique used to detect shapes like lines and circles in an image¹. It converts these shapes into mathematical representations in a parameter space, making it easier to identify them even if they're broken or obscured¹. This method is valuable for image analysis, pattern recognition, and object detection¹.

The Hough Transform was invented by Richard Duda and Peter Hart in 1972². It was initially concerned with the identification of lines in an image, but later it was extended to identifying positions of arbitrary shapes, most commonly circles or ellipses³. The transform works by mapping points in the image space to curves or lines in the parameter space³. By finding the intersections of these curves or lines, you can identify the parameters of the shapes you're interested in³.

Here's an example Python code snippet that demonstrates how to apply the Hough Transform using OpenCV:

import cv2
import numpy as np

# Load the image
image = cv2.imread('your_image.jpg')

# Convert the image to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Apply edge detection (e.g., Canny) to obtain edges
edges = cv2.Canny(gray, 50, 150)

# Apply Hough Transform to detect lines
lines = cv2.HoughLines(edges, 1, np.pi / 180, threshold=100)

# Draw detected lines on the original image
if lines is not None:
    for rho, theta in lines[:, 0]:
        a = np.cos(theta)
        b = np.sin(theta)
        x0 = a * rho
        y0 = b * rho
        x1 = int(x0 + 1000 * (-b))
        y1 = int(y0 + 1000 * (a))
        x2 = int(x0 - 1000 * (-b))
        y2 = int(y0 - 1000 * (a))
        cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)

# Display the result
cv2.imshow('Hough Transform', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

This code snippet demonstrates how to detect lines using the Hough Transform. It first converts the input image to grayscale and applies edge detection using Canny⁴. Then, it applies the Hough Transform using cv2.HoughLines()⁴. Finally, it draws the detected lines on the original image using cv2.line().

Feel free to experiment with different parameters and adapt this code snippet to your specific use case. Good luck with your computer vision project! 🚀

Source: Conversation with Bing, 2023/9/29

  1. (1) A Complete Guide on Hough Transform - Analytics Vidhya. https://www.analyticsvidhya.com/blog/2022/06/a-complete-guide-on-hough-transform/.
  2. (2) . https://bing.com/search?q=Hough+transform+introduction.
  3. (3) Hough transform - Wikipedia. https://en.wikipedia.org/wiki/Hough_transform.
  4. (4) undefined. https://towardsdatascience.com/lines-detection-with-hough-transform-84020b3b1549.
  5. (5) Hough Transform. A comprehensive guide to edge detection ... - Medium. https://medium.com/@st1739/hough-transform-287b2dac0c70.
  6. (6) undefined. https://www.cs.jhu.edu/~misha/Fall04/GHT1.pdf.

user:

When using the Hough transform, if lines unrelated to the edge of the table are detected due to other items on the table, such as milk boxes, and things under the table, such as gaps on the floor, how should we filter and exclude them?

bing:

If you want to filter lines obtained by the Hough Transform that are unrelated to the edge of the table, you can try the following approaches:

  1. Theta Range: You can set the desired theta values in the Hough Transform function to filter lines based on their orientation. For example, if you only want horizontal and vertical lines, you can specify a theta range of 80 to 100 degrees¹.

  2. Line Clustering: After obtaining the lines from the Hough Transform, you can apply clustering algorithms to group similar lines together. For example, you can use the K-means algorithm to cluster lines based on their slope and intercept².

  3. Line Length and Gap: You can filter lines based on their length and gap between line segments. The minLineLength parameter allows you to set a minimum length for line segments, while the maxLineGap parameter specifies the maximum allowed gap between line segments to treat them as a single line³.

These approaches can help you filter out unwanted lines and focus on the ones that are related to the edge of the table. Feel free to experiment with different parameters and adapt them based on your specific requirements.

Let me know if there's anything else I can assist you with!

Source: Conversation with Bing, 2023/9/29

  1. (1) Filtering Hough transform to only find horizontal and vertical lines in .... https://stackoverflow.com/questions/36586088/filtering-hough-transform-to-only-find-horizontal-and-vertical-lines-in-matlab.
  2. (2) Hough Transform. A comprehensive guide to edge detection ... - Medium. https://medium.com/@st1739/hough-transform-287b2dac0c70.
  3. (3) undefined. https://docs.opencv.org/3.4/d6/d10/tutorial_py_houghlines.html.
  4. (4) . https://bing.com/search?q=filter+lines+obtained+by+Hough+transform+independent+of+paper+edges.
  5. (5) Edge Detection, Lines, Hough Transform - University of California, San .... https://cseweb.ucsd.edu/classes/sp07/cse152/lec10.pdf.
  6. (6) %DVHGRQ +RXJK7UDQVIRUP - IOPscience. https://iopscience.iop.org/article/10.1088/1755-1315/440/3/032126/pdf.
  7. (7) Project 4: Feature detection - Scientific Computing and Imaging Institute. https://www.sci.utah.edu/~cscheid/spr05/imageprocessing/project4/.
  8. (8) undefined. https://towardsdatascience.com/lines-detection-with-hough-transform-84020b3b1549.
  9. (9) undefined. https://stackoverflow.com/questions/4709725/explain-hough-transformation.
  10. (10) Algorithm to detect corners of paper sheet in photo. https://stackoverflow.com/questions/6555629/algorithm-to-detect-corners-of-paper-sheet-in-photo.
  11. (11) OpenCV for detecting Edges, lines and shapes - Packt Hub. https://hub.packtpub.com/opencv-detecting-edges-lines-shapes/.
  12. (12) Automatically OCR’ing Receipts and Scans - PyImageSearch. https://pyimagesearch.com/2021/10/27/automatically-ocring-receipts-and-scans/.
  13. (13) . https://bing.com/search?q=how+to+filter+lines+obtained+by+Hough+transform+independent+of+paper+edges.
  14. (14) math - Hough transform filter lines - Stack Overflow. https://stackoverflow.com/questions/20615082/hough-transform-filter-lines.
  15. (15) undefined. http://madteckhead.com/tmp.
  16. (16) undefined. https://scikit-image.org/docs/stable/auto_examples/edges/plot_line_hough_transform.html.

user:

你能翻译成中文再输出一遍吗?

bing:

当所有四个角落的纸张被遮挡时,通过检测边缘来识别纸张变得困难。然而,您仍然可以尝试使用OpenCV检测边缘,按照以下步骤进行操作:

  1. 预处理:应用图像预处理技术,如去噪、图像增强或阈值化,以提高输入图像的质量。

  2. 边缘检测:使用Canny、Sobel或Laplacian等边缘检测算法,在预处理后的图像中检测边缘。这些算法可以帮助识别像素强度的剧烈变化,通常对应于边缘。

  3. 霍夫变换:应用霍夫变换来检测边缘检测图像中的直线或曲线。霍夫变换可以帮助您找到直线或圆等几何形状。

  4. 线段交点:如果使用霍夫变换检测到多条直线,您可以找到它们的交点来识别纸张的角落。交点表示纸张的角落,即使它们被遮挡也是如此。

  5. 纸张分割:一旦您识别出纸张的角落,您可以使用它们将纸张与图像的其他部分分离。这种分割可以帮助将A4纸张单独处理或分析。

请注意,此方法假设至少每个角落的一部分是可见或可检测到的。如果所有四个角都完全被遮挡,仅通过边缘检测可能无法准确识别纸张。

请随意尝试这些步骤,并根据您的具体要求和约束进行调整。祝您在项目中取得成功! 🚀


和chatgpt的对话记录

chatlog

user:

When using the Hough transform, if lines unrelated to the edge of the table are detected due to other items on the table, such as milk boxes, and things under the table, such as gaps on the floor, how should we filter and exclude them?

chatgpt:

Filtering and excluding unwanted lines detected by the Hough transform in the presence of unrelated objects like milk boxes and gaps on the floor can be challenging but can be achieved through a combination of preprocessing, parameter tuning, and post-processing techniques. Here are some strategies to help you filter out unwanted lines:

  1. Preprocessing:

a. Edge Detection: Before applying the Hough transform, use a suitable edge detection algorithm like Canny to extract edges from the image. This will help focus the Hough transform on the most relevant edges.

b. Region of Interest (ROI): Define a region of interest that covers the table area and excludes the surrounding objects like milk boxes and gaps on the floor. Only apply the Hough transform to this ROI.

  1. Parameter Tuning:

a. Hough Transform Parameters: Experiment with different parameter values for the Hough transform, such as the minimum line length and maximum gap between line segments. Adjusting these parameters can help filter out short and fragmented lines.

b. Edge Detection Threshold: Adjust the threshold for edge detection to control the sensitivity of edge detection. Higher thresholds can help reduce noise.

  1. Post-processing:

a. Line Clustering: After detecting lines, you can cluster them based on their proximity in the image. Lines that are close to each other may belong to the same object, while lines far apart are likely unrelated. You can use clustering algorithms like DBSCAN or K-means for this purpose.

b. Angle Filtering: If you know the orientation of the table, you can filter out lines with angles that are significantly different from the expected orientation of the table. This can help eliminate lines associated with objects at different angles.

c. Length Filtering: Discard lines that are shorter than a certain threshold. Short lines are more likely to be noise or unrelated objects.

d. Geometric Constraints: Apply geometric constraints to the detected lines. For example, you can check if lines intersect within a specific area or if they form a closed shape that resembles a table.

  1. Machine Learning-Based Approaches:

a. Train a machine learning model to classify lines as table edges or unrelated objects. You can use annotated data to train a classifier that can differentiate between relevant and irrelevant lines.

  1. Iterative Approach: Sometimes, combining multiple techniques and iterating through them can provide better results. Start with basic filtering techniques and gradually incorporate more advanced methods if needed.

  2. Visual Inspection: In some cases, manual or visual inspection may be necessary to confirm and refine the results of automated filtering techniques.

Keep in mind that the effectiveness of these strategies may vary depending on the complexity of the scene and the quality of the input data. It may require some experimentation and fine-tuning to achieve the desired results.

user:

你能翻译成中文再说一次吗?

chatgpt:

当使用霍夫变换时,如果检测到与桌子边缘无关的线条,例如桌子上的牛奶盒或桌子下的地板缝隙,应该如何进行筛选和排除呢?这可以通过预处理、参数调整和后处理技术的结合来实现。以下是一些帮助您过滤掉不需要的线条的策略:

  1. 预处理:

a. 边缘检测: 在应用霍夫变换之前,使用适当的边缘检测算法如Canny来从图像中提取边缘。这将有助于集中霍夫变换在最相关的边缘上。

b. 感兴趣区域 (ROI): 定义一个感兴趣的区域,覆盖桌子区域,排除周围的物体,如牛奶盒和地板缝隙。只对这个ROI应用霍夫变换。

  1. 参数调整:

a. 霍夫变换参数: 尝试不同的霍夫变换参数值,如最小线段长度和线段之间的最大间隔。调整这些参数可以帮助过滤掉短小和断裂的线段。

b. 边缘检测阈值: 调整边缘检测的阈值,以控制边缘检测的灵敏度。较高的阈值可以帮助减少噪音。

  1. 后处理:

a. 线条聚类: 在检测到线段后,您可以根据它们在图像中的接近程度进行聚类。彼此接近的线条可能属于同一物体,而相距较远的线条可能与不相关物体有关。您可以使用聚类算法,如DBSCAN或K均值,来实现这一目的。

b. 角度过滤: 如果您知道桌子的方向,可以过滤掉与桌子预期方向明显不同的线条。这有助于消除与不同角度的物体相关的线条。

c. 长度过滤: 丢弃长度低于某个阈值的线条。短线条更可能是噪音或与无关物体有关。

d. 几何约束: 对检测到的线条应用几何约束。例如,您可以检查线条是否在特定区域内相交,或者它们是否形成了类似桌子的封闭形状。

  1. 基于机器学习的方法:

a. 训练一个机器学习模型,将线条分类为桌子边缘或与之无关的物体。您可以使用已标注的数据来训练一个分类器,以区分相关和无关的线条。

  1. 迭代方法: 有时,结合多种技术并迭代使用它们可以提供更好的结果。从基本的过滤技术开始,逐渐引入更高级的方法,如果需要的话。

  2. 视觉检查: 在某些情况下,可能需要手动或视觉检查来确认和细化自动筛选技术的结果。

请注意,这些策略的有效性可能会根据场景的复杂性和输入数据的质量而有所不同。可能需要一些实验和微调才能达到期望的结果。

user:

then how to Define a region of interest that covers the table area and excludes the surrounding objects?

chatgpt:

定义一个感兴趣区域 (ROI),覆盖桌子区域并排除周围的物体,可以通过以下步骤来实现:

  1. 图像预览: 首先,您需要查看图像或视频帧,以确定感兴趣的区域以及要排除的物体。这将帮助您精确地定义ROI。

  2. ROI 坐标: 确定ROI的坐标和形状。通常,ROI是一个矩形或多边形。您可以使用图像坐标系中的左上角和右下角坐标来定义矩形ROI,或者使用一系列坐标点来定义多边形ROI。

  3. 代码实现: 在代码中,根据您的定义,创建一个与ROI相对应的掩码(mask)。掩码是一个与原始图像具有相同大小的二进制图像,其中ROI内的像素值为1,而ROI外的像素值为0。

  4. 如果您使用Python和OpenCV,可以使用以下代码创建ROI掩码:

import cv2
import numpy as np

# 创建与图像大小相同的黑色掩码
mask = np.zeros_like(original_image)

# 定义ROI的顶点坐标
roi_vertices = np.array([[(x1, y1), (x2, y2), (x3, y3), (x4, y4)]], dtype=np.int32)

# 在掩码上绘制ROI区域
cv2.fillPoly(mask, roi_vertices, 255)

# 应用掩码到原始图像
masked_image = cv2.bitwise_and(original_image, mask)

在上面的代码中,roi_vertices包含ROI的顶点坐标,您可以根据实际情况修改这些坐标以匹配桌子的位置和形状。然后,使用cv2.fillPoly函数将ROI区域填充为白色(像素值为255),并使用cv2.bitwise_and将掩码应用到原始图像上。

  1. 进一步处理: 一旦您获得了ROI内的图像区域,您可以在这个区域上执行边缘检测、霍夫变换或其他图像处理操作,以便在感兴趣的区域内执行特定的任务,如检测桌子的边缘线。

确保根据您的具体应用场景和图像来调整ROI的定义和坐标,以确保它包含您感兴趣的区域并排除不需要的部分。

user:

can we talk in english?

chatgpt:

Of course, we can continue in English. Please feel free to ask any questions or discuss any topics you'd like.

user:

So how do I define a region of interest that covers the table area and excludes the surrounding objects in the images returned by the camera?

chatgpt:

Defining a region of interest (ROI) in images captured by a camera to cover the table area while excluding surrounding objects involves a few steps:

  1. Capture and Preprocess Images:
  2. First, capture or obtain the images from your camera.
  3. Preprocess the images if necessary. This might include resizing, cropping, or adjusting the brightness and contrast to enhance the quality of the images for further processing.

  4. Identify the Table Area:

  5. Depending on the characteristics of your table, you can use computer vision techniques to identify the table area within the images. Common approaches include color-based segmentation, object detection, or edge detection. For example, if the table has a distinct color or shape, you can use color thresholding or shape recognition to identify it.

  6. Define the ROI:

  7. Once you've identified the table area, determine the coordinates or boundaries of the ROI. This can be done manually if the position of the table is consistent in your images. Alternatively, you can use the coordinates of the detected table area to define the ROI programmatically.

  8. Create a Mask:

  9. Create a binary mask with the same dimensions as your image, where the region you want to keep is set to 1 (white) and the surrounding area is set to 0 (black). You can use libraries like OpenCV to create and apply masks.
import cv2
import numpy as np

# Create a black mask with the same size as the image
mask = np.zeros_like(image)

# Define the coordinates of the ROI (for example, as a rectangular region)
x1, y1 = top-left corner coordinates
x2, y2 = bottom-right corner coordinates

# Fill the ROI region with white (1)
cv2.rectangle(mask, (x1, y1), (x2, y2), (255, 255, 255), thickness=cv2.FILLED)

# Apply the mask to the original image
result = cv2.bitwise_and(image, mask)

Adjust the coordinates (x1, y1) and (x2, y2) to match your specific table's position and size.

  1. Extract the ROI:
  2. Finally, you can extract the region of interest (the table area) from the original image using the mask you created. The result variable in the above code will contain the ROI.

By following these steps, you can define an ROI in the images returned by your camera to focus on the table area while excluding the surrounding objects. Remember to adapt the process based on the specific characteristics of your images and table.

user:

你能将这条信息翻译成中文吗?

chatgpt:

当从摄像头捕获图像并希望定义一个感兴趣区域 (ROI),以覆盖桌面区域并排除周围的物体时,需要执行以下几个步骤:

  1. 捕获和预处理图像:
  2. 首先,从摄像头捕获或获取图像。
  3. 如果需要,对图像进行预处理。这可能包括调整大小、裁剪或调整亮度和对比度,以增强图像的质量以便进行进一步处理。

  4. 识别桌面区域:

  5. 根据您的桌面特征,您可以使用计算机视觉技术来在图像中识别桌面区域。常见的方法包括基于颜色的分割、物体检测或边缘检测。例如,如果桌面具有明显的颜色或形状,您可以使用颜色阈值或形状识别来标识它。

  6. 定义ROI:

  7. 一旦您识别出桌面区域,确定ROI的坐标或边界。如果桌面在图像中的位置保持一致,您可以手动进行定义。或者,您可以使用程序化的方式,使用检测到的桌面区域的坐标来定义ROI。

  8. 创建掩码:

  9. 创建一个二进制掩码,其尺寸与图像相同,其中您要保留的区域设置为1(白色),周围区域设置为0(黑色)。您可以使用诸如OpenCV之类的库来创建和应用掩码。
import cv2
import numpy as np

# 创建与图像尺寸相同的黑色掩码
mask = np.zeros_like(image)

# 定义ROI的坐标(例如,矩形区域的顶点坐标)
x1, y1 = 左上角坐标
x2, y2 = 右下角坐标

# 用白色(1)填充ROI区域
cv2.rectangle(mask, (x1, y1), (x2, y2), (255, 255, 255), thickness=cv2.FILLED)

# 将掩码应用于原始图像
result = cv2.bitwise_and(image, mask)

根据您的特定桌面的位置和大小,调整坐标 (x1, y1)(x2, y2)

  1. 提取ROI:
  2. 最后,您可以使用创建的掩码从原始图像中提取感兴趣区域(桌面区域)。上述代码中的 result 变量将包含ROI。

通过按照这些步骤操作,您可以在摄像头返回的图像中定义一个感兴趣区域,以便聚焦在桌面区域,同时排除周围的物体。请根据您的图像和桌面的具体特征来调整此过程。

user:

However, the image returned by the camera itself has many objects on the desktop, which can interfere with the segmentation of the desktop. For example, it may block some corners and edges of the table, so how will ROI be defined

chatgpt:

When the image returned by the camera contains multiple objects on the desktop that can interfere with the segmentation of the table, defining an ROI can be more challenging. In such cases, you can consider the following strategies to define the ROI effectively:

  1. Background Subtraction:
  2. Apply background subtraction techniques to separate the foreground (objects on the table) from the background (the table itself). This can help in identifying the table area without the interference of other objects.

  3. Object Detection and Removal:

  4. Use object detection algorithms (e.g., YOLO, SSD, Faster R-CNN) to detect and identify objects on the table. Once objects are detected, you can remove or mask them from the image, leaving only the table area.

  5. Multiple ROIs:

  6. If the objects on the table are distinct from the table itself, consider defining multiple ROIs that cover different regions of the image. Each ROI can focus on a specific part of the table while excluding objects in other regions.

  7. Adaptive ROI:

  8. Use an adaptive approach where the ROI is adjusted dynamically based on the detected objects. For instance, you can calculate the bounding box of the detected table and then expand or contract the ROI based on the table's position and size.

  9. Contour Detection:

  10. Use contour detection to identify the outline of the table even when partially obstructed by objects. Once you have the table's contour, you can create an ROI that encompasses the entire contour.

  11. Depth Information:

  12. If depth information is available (e.g., from a depth-sensing camera or stereo vision setup), you can use it to estimate the height or depth of objects on the table. This information can help distinguish between the table surface and objects.

  13. Machine Learning:

  14. Train a machine learning model to classify pixels or regions as part of the table or as objects. This model can assist in defining the ROI by segmenting the table area.

  15. Manual Annotation:

  16. In some cases, manual annotation may be necessary to define the ROI accurately. You can manually draw or adjust the ROI on the image.

  17. Combine Techniques:

  18. Often, a combination of these techniques may be the most effective solution. Start with background subtraction or object detection to identify the table, and then refine the ROI using contour detection or manual adjustments if needed.

Defining an ROI in the presence of obstructing objects requires a flexible and adaptive approach. The choice of method will depend on the specific characteristics of your images and the nature of the objects on the table. Experimentation and fine-tuning may be necessary to achieve the best results.

user:

将这条消息翻译成中文

chatgpt:

当摄像头返回的图像上有多个物体放在桌面上,可能干扰到桌面的分割,定义一个感兴趣区域(ROI)可能会更具挑战性。在这种情况下,您可以考虑以下策略来有效定义ROI:

  1. 背景减除:
  2. 应用背景减除技术,将前景(桌面上的物体)与背景(桌子本身)分离开来。这有助于在没有其他物体干扰的情况下识别桌面区域。

  3. 物体检测和移除:

  4. 使用物体检测算法(例如YOLO、SSD、Faster R-CNN)来检测和识别桌面上的物体。一旦物体被检测到,您可以从图像中删除或遮挡它们,只留下桌面区域。

  5. 多个ROI:

  6. 如果桌面上的物体与桌子本身不同,考虑定义多个ROI,涵盖图像的不同区域。每个ROI可以聚焦在桌子的特定部分,同时排除其他区域的物体。

  7. 自适应ROI:

  8. 使用自适应方法,根据检测到的物体动态调整ROI。例如,您可以计算检测到的桌子的边界框,然后根据桌子的位置和大小扩展或收缩ROI。

  9. 轮廓检测:

  10. 使用轮廓检测来识别桌子的轮廓,即使它在一部分区域被物体部分遮挡。一旦获得桌子的轮廓,您可以创建一个ROI,包含整个轮廓。

  11. 深度信息:

  12. 如果有深度信息可用(例如来自深度传感摄像头或立体视觉设置),您可以使用它来估计桌子上物体的高度或深度。这些信息可以帮助区分桌子表面和物体。

  13. 机器学习:

  14. 训练一个机器学习模型,将像素或区域分类为桌子的一部分或物体。该模型可以协助定义ROI,通过对图像进行分割。

  15. 手动标注:

  16. 在某些情况下,可能需要手动标注来准确定义ROI。您可以在图像上手动绘制或调整ROI。

  17. 结合技术:

  18. 通常,这些技术的组合可能是最有效的解决方案。首先使用背景减除或物体检测来识别桌子,然后根据需要使用轮廓检测或手动调整来细化ROI。

在存在干扰物体的情况下定义ROI需要一种灵活和自适应的方法。方法的选择将取决于您的图像的具体特点以及桌面上物体的性质。可能需要进行实验和微调以获得最佳结果。

user:

How to set Adaptive ROI

chatgpt:

Setting an adaptive Region of Interest (ROI) involves dynamically adjusting the ROI based on the specific conditions or objects in your image. This can be done programmatically using computer vision techniques. Here's a general outline of how to set up an adaptive ROI:

  1. Initialize an Initial ROI:
  2. Start by defining an initial ROI that covers the region you're interested in. This can be a rectangular area, a polygon, or any shape that encompasses the expected location of your target object (e.g., the table in your case).

  3. Image Preprocessing (if necessary):

  4. Preprocess your image as needed. This can include tasks like resizing, color correction, or noise reduction.

  5. Object Detection or Segmentation:

  6. Implement an object detection or segmentation algorithm to identify the objects or features of interest in your image. For your scenario, this might involve identifying the table.

  7. Adjust the ROI Dynamically:

  8. Based on the results of your object detection or segmentation, calculate a new ROI that better fits the detected object. You can adjust the size, position, or shape of the ROI accordingly.
  9. For example, if the table is detected as a bounding box, you can use the coordinates of this bounding box to define the new ROI. You may also expand or shrink the ROI to ensure the entire table is included.

  10. Apply the Adaptive ROI:

  11. Use the newly calculated ROI to extract the region of interest from the original image. You can use this ROI for further analysis or processing.
  12. Depending on your programming environment (e.g., Python with OpenCV), you can use functions like cv2.rectangle to define the ROI coordinates.

Here's a simplified example in Python using OpenCV to illustrate the concept:

import cv2

# Initial ROI (example values)
x1, y1, x2, y2 = initial_roi_coordinates

while True:
    # Capture a frame from the camera or load an image

    # Perform object detection or segmentation (e.g., detect the table)

    # Calculate the new adaptive ROI based on detection results
    x1, y1, x2, y2 = calculate_adaptive_roi(detection_results)

    # Extract the adaptive ROI from the frame
    roi = frame[y1:y2, x1:x2]

    # Further processing with the ROI

    # Display the result (if needed)

    # Break the loop when done or under specific conditions
    if done_condition:
        break

In this example, initial_roi_coordinates represent the initial region of interest. During each iteration, you calculate a new ROI based on detection results and use it to extract the relevant part of the frame for further processing. Repeat this process in a loop as long as necessary.

Remember that the specific implementation details will depend on your object detection or segmentation method and how you adjust the ROI based on those results.

user:

将这条消息翻译成中文

chatgpt:

设置自适应感兴趣区域(ROI)涉及根据图像中的特定条件或物体动态调整ROI。这可以通过计算机视觉技术在程序中完成。以下是如何设置自适应ROI的一般概述:

  1. 初始化初始ROI:
  2. 首先,定义一个初始ROI,覆盖您感兴趣的区域。这可以是一个矩形区域、多边形或任何形状,包含您目标对象的预期位置(例如,在您的情况下是桌子)。

  3. 图像预处理(如果需要):

  4. 根据需要对图像进行预处理。这可以包括调整大小、颜色校正或降噪等任务。

  5. 对象检测或分割:

  6. 实施对象检测或分割算法,以识别图像中感兴趣的物体或特征。对于您的情况,这可能涉及到识别桌子。

  7. 动态调整ROI:

  8. 根据对象检测或分割的结果,计算一个新的ROI,更好地适应检测到的物体。您可以相应地调整ROI的大小、位置或形状。
  9. 例如,如果桌子被检测为边界框,您可以使用这个边界框的坐标来定义新的ROI。您还可以根据需要扩展或缩小ROI,以确保包括整个桌子。

  10. 应用自适应ROI:

  11. 使用新计算的ROI从原始图像中提取感兴趣区域。您可以将此ROI用于进一步的分析或处理。
  12. 根据您的编程环境(例如,Python与OpenCV),您可以使用cv2.rectangle等函数来定义ROI的坐标。

以下是一个使用Python和OpenCV简化示例,以说明这一概念:

import cv2

# 初始ROI(示例值)
x1, y1, x2, y2 = 初始ROI的坐标

while True:
    # 从摄像机捕获一帧或加载一张图像

    # 执行对象检测或分割(例如,检测桌子)

    # 根据检测结果计算新的自适应ROI
    x1, y1, x2, y2 = 计算自适应ROI(检测结果)

    # 从帧中提取自适应ROI
    roi = [y1:y2, x1:x2]

    # 对ROI进行进一步处理

    # 显示结果(如果需要)

    # 在完成或满足特定条件时退出循环
    if 完成条件:
        break

在此示例中,初始ROI的坐标表示初始感兴趣区域。在每次迭代中,您都根据检测结果计算一个新的ROI,并用它来提取帧的相关部分以进行进一步处理。根据需要重复这个过程直到满足条件。

请记住,具体的实现细节将取决于您的对象检测或分割方法以及如何根据这些结果调整ROI。


另一种通过检测在同一平面的同色色块来识别桌面的思路

需要从相机读取的信息中计算出球坐标系下的坐标再转换成直角坐标系坐标

想法是,由于r坐标可以由深度帧直接获取,所以打算将rgb图像上的x,y坐标转换成球坐标系下的角度

chatlog

user:

I want to calculate the coordinates of an object in the spherical coordinate system with the camera as the origin based on the data obtained by the depth camera, and the r coordinate can be directly read from the depth frame. Therefore, how to convert the x y coordinate in the rgb image frame into the coordinates of two angles in the spherical coordinate system

chatgpt:

To convert the 2D coordinates (x, y) from an RGB image frame into spherical coordinates (θ, φ, r) with the camera as the origin, you can use trigonometry and basic geometry. Here are the steps to perform this conversion:

  1. Capture Depth Information: You mentioned that you have the depth information (r coordinate) already obtained from the depth camera. Make sure you have this information corresponding to the RGB image.

  2. Coordinate Transformation: Convert the 2D coordinates (x, y) in the RGB image frame to a 3D point (X, Y, Z) in the camera's coordinate system. The Z-coordinate is the depth value (r) you obtained.

  3. X = (x - center_x) * r / focal_length_x

  4. Y = (y - center_y) * r / focal_length_y
  5. Z = r

Where: - (center_x, center_y) are the coordinates of the optical center of the RGB camera. - (focal_length_x, focal_length_y) are the focal lengths of the RGB camera.

  1. Spherical Coordinate Conversion:

  2. Calculate the radial distance (r) directly from the depth frame.

  3. Calculate the azimuth angle (θ) as the arctan of Y and X:

    θ = arctan2(Y, X)

  4. Calculate the polar angle (φ) as the arctan of the square root of (X^2 + Y^2) and Z:

    φ = arctan2(sqrt(X^2 + Y^2), Z)

Now you have the spherical coordinates (θ, φ, r) of the object with the camera as the origin.

Here's a Python code example to perform these calculations:

import numpy as np

# Input data
x = 320  # Example x-coordinate in the RGB image
y = 240  # Example y-coordinate in the RGB image
r = 3.0  # Example depth value from the depth frame
focal_length_x = 500.0  # Focal length in the x-direction
focal_length_y = 500.0  # Focal length in the y-direction
center_x = 320  # Optical center x-coordinate
center_y = 240  # Optical center y-coordinate

# Convert 2D coordinates to 3D point
X = (x - center_x) * r / focal_length_x
Y = (y - center_y) * r / focal_length_y
Z = r

# Calculate spherical coordinates
theta = np.arctan2(Y, X)
phi = np.arctan2(np.sqrt(X**2 + Y**2), Z)

# Output spherical coordinates
print(f"Theta (Azimuth Angle): {theta} radians")
print(f"Phi (Polar Angle): {phi} radians")
print(f"R (Radial Distance): {r} units")

This code takes the x and y coordinates from the RGB image, the depth value (r), and the camera parameters (focal lengths and optical center) to calculate the spherical coordinates (θ, φ, r) of the object in the camera's coordinate system.

user:

你能翻译成中文再输出一次吗?

chatgpt:

当你想要将RGB图像帧中的2D坐标(x,y)转换为以摄像机为原点的球坐标(θ,φ,r)时,你可以使用三角几何和基本几何学知识来进行转换。以下是执行此转换的步骤:

  1. 获取深度信息:你提到已经从深度相机获取了深度信息(r坐标)。确保这个信息与RGB图像对应。

  2. 坐标变换:将RGB图像帧中的2D坐标(x,y)转换为摄像机坐标系中的3D点(X,Y,Z)。Z坐标就是你得到的深度值(r)。

  3. X = (x - center_x) * r / focal_length_x

  4. Y = (y - center_y) * r / focal_length_y
  5. Z = r

其中: - (center_x,center_y)是RGB摄像机的光学中心坐标。 - (focal_length_x,focal_length_y)是RGB摄像机的焦距。

  1. 球坐标转换

  2. 直接从深度帧中计算径向距离(r)。

  3. 计算方位角(θ)为Y和X的反正切值:

    θ = arctan2(Y,X)

  4. 计算极角(φ)为sqrt(X^2 + Y^2)和Z的反正切值:

    φ = arctan2(sqrt(X^2 + Y^2),Z)

现在你有了以摄像机为原点的球坐标(θ,φ,r)。

以下是一个执行这些计算的Python代码示例:

import numpy as np

# 输入数据
x = 320  # RGB图像中的示例x坐标
y = 240  # RGB图像中的示例y坐标
r = 3.0  # 从深度帧获取的示例深度值
focal_length_x = 500.0  # x方向的焦距
focal_length_y = 500.0  # y方向的焦距
center_x = 320  # 光学中心x坐标
center_y = 240  # 光学中心y坐标

# 将2D坐标转换为3D点
X = (x - center_x) * r / focal_length_x
Y = (y - center_y) * r / focal_length_y
Z = r

# 计算球坐标
theta = np.arctan2(Y, X)
phi = np.arctan2(np.sqrt(X**2 + Y**2), Z)

# 输出球坐标
print(f"方位角(θ):{theta} 弧度")
print(f"极角(φ):{phi} 弧度")
print(f"径向距离(r):{r} 单位")

这段代码使用来自RGB图像的x和y坐标、深度值(r)以及摄像机参数(焦距和光学中心)来计算摄像机坐标系中对象的球坐标(θ,φ,r)。

user:

Can you explain these two lines

X = (x - center_x) * r / focal_length_x
Y = (y - center_y) * r / focal_length_y

chatgpt:

Certainly! These two lines of code are responsible for converting 2D image coordinates (x, y) from the RGB image frame into 3D coordinates (X, Y, Z) in the camera's coordinate system. Let's break down these lines step by step:

  1. (x - center_x) and (y - center_y): These parts of the equations calculate the displacement of the 2D point (x, y) from the optical center of the camera. The optical center, represented by (center_x, center_y), is the point where the optical axis intersects the image plane. By subtracting the optical center coordinates from the image coordinates, you get the offset of the point from the center in the x and y directions.

  2. (x - center_x) * r / focal_length_x and (y - center_y) * r / focal_length_y: These parts of the equations scale the displacements in the x and y directions by the depth value (r) and the focal lengths (focal_length_x and focal_length_y) of the camera.

  3. (x - center_x) * r scales the x-displacement based on depth, effectively moving the point along the camera's x-axis in 3D space. This operation ensures that the point's position in 3D space corresponds to its position in the 2D image plane, considering depth.

  4. / focal_length_x then scales the x-displacement by the focal length in the x-direction. This step ensures that the units of the resulting X-coordinate are consistent with the units of the focal length, typically in pixels or millimeters. It effectively converts the displacement from pixel units to real-world units.

  5. Similarly, (y - center_y) * r scales the y-displacement based on depth and / focal_length_y scales it by the focal length in the y-direction. This operation is for the y-coordinate, converting it from pixel units to real-world units.

The final result is the 3D coordinates (X, Y, Z) of the point in the camera's coordinate system, where X and Y are in the horizontal and vertical directions in the camera's plane, and Z represents the depth from the camera to the point.

These equations are fundamental for projecting 2D image points into 3D space using camera parameters and depth information.

user:

你能翻译成中文再输出一次吗?

chatgpt:

当然可以!以下是这两行代码的解释,这些代码用于将RGB图像帧中的2D图像坐标(x,y)转换为摄像机坐标系中的3D坐标(X,Y,Z)。我们逐步解释这两行代码:

  1. (x - center_x)(y - center_y):这部分代码计算了2D点(x,y)相对于摄像机光学中心的位移。光学中心由(center_x, center_y)表示,它是光学轴与图像平面相交的点。通过从图像坐标中减去光学中心坐标,你得到了点相对于中心的x和y方向上的偏移。

  2. (x - center_x) * r / focal_length_x(y - center_y) * r / focal_length_y:这部分代码根据深度值(r)和摄像机的焦距(focal_length_x和focal_length_y)对x和y方向上的偏移进行了缩放。

  3. (x - center_x) * r 根据深度值对x方向上的偏移进行了缩放,实际上是将点沿着摄像机的x轴在3D空间中移动。这个操作确保了点在3D空间中的位置与其在2D图像平面中的位置相对应,考虑到深度。

  4. / focal_length_x 然后通过x方向上的焦距对x方向上的偏移进行了缩放。这一步确保了结果X坐标的单位与焦距的单位一致,通常是像素或毫米。它实际上将偏移从像素单位转换为实际世界单位。

  5. 类似地,(y - center_y) * r 根据深度值对y方向上的偏移进行了缩放,/ focal_length_y 通过y方向上的焦距对y方向上的偏移进行了缩放。这个操作是为了y坐标,将其从像素单位转换为实际世界单位。

最终的结果是点在摄像机坐标系中的3D坐标(X,Y,Z),其中X和Y分别表示摄像机平面中的水平和垂直方向,而Z表示从摄像机到点的深度。

这些方程式是使用摄像机参数和深度信息将2D图像点投影到3D空间的基础,非常重要。

user:

How should I obtain information related to focal length

chatgpt:

Obtaining information related to the focal length of a camera typically depends on the camera model and manufacturer. Here are several common methods to obtain information about the focal length of a camera:

  1. Camera Documentation: The easiest way to find information about the camera's focal length is to consult the camera's user manual or technical documentation. Manufacturers often provide detailed specifications, including the focal length of the camera's lens or lenses.

  2. Camera Settings: Some cameras, especially digital cameras and DSLRs, display information about the focal length in their settings menus or on the camera's LCD screen. Check your camera's settings or display options to see if the focal length is listed.

  3. Camera Lens Markings: On interchangeable lens cameras, such as DSLRs and mirrorless cameras, the focal length of the lens is usually marked on the lens itself. Look for markings like "18-55mm" or "50mm" on the lens barrel. These markings indicate the range of focal lengths for zoom lenses or the fixed focal length for prime lenses.

  4. Online Resources: If you don't have access to the camera's documentation or markings, you can often find information about camera specifications, including focal length, on the manufacturer's website or on photography equipment review websites.

  5. EXIF Data: For digital photos taken with the camera, you can often find information about the focal length in the photo's EXIF metadata. You can use software or online EXIF viewers to access this information.

  6. Contact the Manufacturer: If you can't find the information you need through the above methods, consider reaching out to the camera manufacturer's customer support or technical support. They may be able to provide you with the specific focal length information for your camera model.

  7. Measure it Directly: If you have access to the camera and the necessary equipment, you can measure the focal length of a camera lens experimentally using methods like the "back focal length" measurement or by conducting tests with known objects and distances.

Remember that cameras with zoom lenses may have a range of focal lengths (e.g., 18-55mm), and prime lenses have a fixed focal length (e.g., 50mm). If you have an interchangeable lens camera, you may need to consider the specific lens you are using when determining the focal length.

user:

你能翻译成中文再输出一次吗?

chatgpt:

获取相机焦距信息通常取决于相机型号和制造商。以下是获取有关相机焦距信息的几种常见方法:

  1. 相机文档:获取有关相机焦距的最简单方法是查阅相机的用户手册或技术文档。制造商通常会提供详细的规格信息,包括相机镜头或镜头的焦距。

  2. 相机设置:一些相机,特别是数码相机和单反相机,会在其设置菜单或相机的LCD屏幕上显示焦距信息。检查相机的设置或显示选项,看看焦距是否列出。

  3. 相机镜头标记:在可更换镜头的相机上,例如单反相机和无反光相机,镜头的焦距通常标在镜头本身上。查找镜头筒上的标记,例如“18-55mm”或“50mm”。这些标记表示变焦镜头的焦距范围或定焦镜头的固定焦距。

  4. 在线资源:如果无法访问相机文档或标记,通常可以在制造商的网站或摄影设备评论网站上找到有关相机规格的信息,包括焦距。

  5. EXIF数据:对于使用相机拍摄的数字照片,通常可以在照片的EXIF元数据中找到有关焦距的信息。您可以使用软件或在线EXIF查看器访问此信息。

  6. 联系制造商:如果通过上述方法找不到所需的信息,可以考虑联系相机制造商的客户支持或技术支持部门。他们可能能够为您提供特定相机型号的焦距信息。

  7. 直接测量:如果您可以访问相机和必要的设备,可以使用实验方法(如“背焦距”测量)或通过与已知物体和距离进行测试来实验性地测量相机镜头的焦距。

请记住,具有变焦镜头的相机可能具有一系列焦距(例如,18-55mm),而定焦镜头具有固定焦距(例如,50mm)。如果您使用的是可更换镜头相机,确定焦距时可能需要考虑您正在使用的特定镜头。

10.1

我们想到一个新的分割掉桌面以外的可能的方法,

通过深度帧中的检测,默认帧的中心就是桌面上,然后从中心向四周进行检测,如果相邻的像素之间,深度的差值过大(即超过设置的某个值),就判断这一点是桌面的边界

(我的想法还有一点,为了使得边界能连在一起,所以在判断出是边界之后,边界往外的垂直方向上,可以向外扩展几个像素也认为是边界以外。或者使用一些类似于高斯模糊的操作进行预处理,使得边界变得平整/连续)

10.2

jetson nano cmake 找不到 openssl

报错信息

CMake Error at Utilities/cmcurl/CMakeLists.txt:608 (message):
  Could not find OpenSSL.  Install an OpenSSL development package or
  configure CMake with -DCMAKE_USE_OPENSSL=OFF to build without OpenSSL

尝试过的几个没成功的方法:

  • cmake-x.xx.x/CMakeLists.txtcmake-x.xx.x/Utilities/cmcurl/CMakeLists.txt 中都添加了 set(CMAKE_USE_OPENSSL OFF) ,但没用

  • ```bash yum install openssl openssl-devel

    显示 `yum` 没装,然后安装 `yum`
    
    ```bash
    sudo apt install yum
    

    但是运行 yum --version 的时候,一直有报错,尝试修改也无用

成功的解决方法

sudo apt install libssl-dev

桌面识别/分割算法方面

我认为,直接调用深度相机在窗口中显示出来的图片,可能不能直接从图像上获取到准确的深度值,所以想尝试能不能直接通过深度相机读取获得深度帧的数据(或者说成一个矩阵)

10.4

解决在pycharm中导入 pyorbbecsdk 包的问题

之间下载并编译好 Orbbec SDK 之后,都是只能在终端/命令行中使用,pycharm中 from pyorbbecsdk import * 时会显示没有 pyorbbecsdk 模块

Traceback (most recent call last):
  File "E:\Github\pyorbbecsdk\examples\depth_color_sync_align_viewer.py", line 16, in <module>
    from pyorbbecsdk import *
ModuleNotFoundError: No module named 'pyorbbecsdk'

而中午和下午在复现代码时,找到了在 pycharm 中能正常导入自定义的 .pyc 文件( pyorbbecsdk.cp310-win_amd64.pyc )的方法:

设置 - 项目 - Python解释器 - 在 Python 解释器: 右侧的框的右侧点击向下的三角/箭头 - 全部显示 - 在左上角图标中找到 显示解释器路径 - 添加相应的路径

然后添加上 E:\Github\pyorbbecsdk\install\lib 的路径(具体每个人不一样),就能在pycharm中运行python文件了(即使 from pyorbbecsdk import * 还是会显示红色的警告)

jetson nano 配置环境方面

晚上在 jetson nano 上装 opencv-python 包,但是每次 pip3 install opencv_python-xxxxx.whl 文件时,总是会自动搜索安装 numpy 包,说是 每次 是因为,我们尝试了

  • 安装更高版本的 numpy (因为有 numpy 包的最低版本要求),但是都已经满足最低版本的要求也还是在 pip3 install opencv-python 时会自动搜索 numpy 进行安装
  • 降低 opencv-python 的版本进行安装,尝试安装 opencv_python-4.5.5.64 ,在已经有 numpy 并且版本高于最低版本要求时,也还是会出现这个情况

但在这个过程中,有几个值得注意的地方,我们期间下载过

使用 pip3 install 安装时,均需要修改文件名,否则会报错

需要将文件名改成 xxx-linux_aarch64.whl 才能安装


之后发现,pip 已经安装了 4.6.0 的 opencv-python,但在运行时,会发生错误

>>> import cv2
Illegal instruction (core dumped)

然后程序/终端就会停止/崩溃

然后在网上搜索相应的信息时,发现了很多极其类似的情况

然而他们都提到/引用了 github 的一个 issue

Illegal instruction (core dumped) on import for numpy 1.19.5 on ARM64 · Issue #18131 · numpy/numpy (github.com)

NVIDIA 上的那个问题的回答指向issue上pwoolvett的回答,而它又指向了martin-frbg的回答,这个回答和 stackoverflow 上的 Vladimir Simoes da Luz Junior 的回答 一样,或者说后者参考了前者

所以,方法就是,在 ~/.bashrc 文件的最后添加上

export OPENBLAS_CORETYPE=ARMV8

然后重启一下,

最后在终端中打开python,能正常 import cv2

从相机读取深度数据方面

我们参考 Orbbec SDK for Python 使用手册 - 视频数据获取 以及 ./examples/depth_viewer.py 编写了一个 test.py

from pyorbbecsdk import *
import cv2
import numpy as np
import time

config = Config()
pipeline = Pipeline()

profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
depth_profile = profile_list.get_video_stream_profile(640, 0, OBFormat.Y16, 30)

config.enable_stream(depth_profile)
pipeline.start(config)

while True:
    frames = pipeline.wait_for_frames(100)
    depth_frame = frames.get_depth_frame()

    depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)

    depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)

    cv2.imshow("Depth Viewer", depth_image)
    key = cv2.waitKey(1)
    if key == ord('q') or key == ESC_KEY:
        break


pipeline.stop()
  1. 发现 depth_frame = frames.get_depth_frame() 这一行会出现 NoneType 没有属性的报错,所以在 frames = pipeline.wait_for_frames(100) 后添加上了

        if frames is None:
            continue
    
  2. 发现需要添加上 width height 才能正常显示画面窗口,所以

        width = depth_frame.get_width()
        height = depth_frame.get_height()
    
        depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
        depth_data = depth_data.reshape((height, width))
    

所以复刻出了一个 depth_viewer.py 的简单版本

from pyorbbecsdk import *
import cv2
import numpy as np
import time

config = Config()
pipeline = Pipeline()

profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
depth_profile = profile_list.get_video_stream_profile(640, 0, OBFormat.Y16, 30)

config.enable_stream(depth_profile)
pipeline.start(config)

while True:
    frames = pipeline.wait_for_frames(100)
    if frames is None:
        continue
    depth_frame = frames.get_depth_frame()

    width = depth_frame.get_width()
    height = depth_frame.get_height()

    depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
    depth_data = depth_data.reshape((height, width))

    depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)

    cv2.imshow("Depth Viewer", depth_image)
    key = cv2.waitKey(1)
    if key == ord('q') or key == ESC_KEY:
        break


pipeline.stop()

然后我们开始尝试直接获取出深度帧的数据

    ...

    depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
    depth_data = depth_data.reshape((height, width))

    depth_arr = np.array(depth_data)
    print(depth_arr)
    # depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
    # depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)
    #
    # cv2.imshow("Depth Viewer", depth_image)
    key = cv2.waitKey(1)
    if key == ord('q') or key == ESC_KEY:
        break

发现可以输出numpy的数组,但是显示的几个有限的元素都是 0 (仅显示了四个角落的几个数据),

所以打算看看帧中心的数据是否为 0

    depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
    depth_data = depth_data.reshape((height, width))

    depth_arr = np.array(depth_data)
    print(depth_arr[height // 2][width // 2])

发现能输出不是0的数据,

然后加上了 depth_viewer.py 中的输出中心数据的代码,对比输出的数据

    depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
    depth_data = depth_data.reshape((height, width))

    center_y = int(height / 2)
    center_x = int(width / 2)
    center_distance = depth_data[center_y, center_x]
    print("center distance: ", center_distance)

    depth_arr = np.array(depth_data)
    print(depth_arr[height // 2][width // 2])

发现输出的数据一样,所以应该是拿到了深度的数据


然后我想试试看能不能根据某一帧的深度数据,来画出图像,然后我让chatgpt生成了相应的函数

chatlog

user:

How to Display a 2D Numpy Array as a 3D Coordinate Point Set in python

chatgpt:

Displaying a 2D NumPy array as a 3D coordinate point set in Python involves converting the 2D array into a 3D format where each point in the array is assigned a z-coordinate. You can then use libraries like matplotlib to visualize the 3D point cloud. Here's a step-by-step guide:

  1. Import the necessary libraries:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
  1. Create your 2D NumPy array. Each row of the array should represent a point with x and y coordinates.
# Example 2D array with x and y coordinates
points_2d = np.array([[1.0, 2.0],
                      [2.0, 3.0],
                      [3.0, 1.0],
                      [4.0, 4.0]])
  1. Create a 3D representation of the points by assigning a z-coordinate to each point. You can set a constant z-coordinate or compute it based on some criteria.
# Assign a constant z-coordinate (e.g., 0) to all points
points_3d = np.column_stack((points_2d, np.zeros(len(points_2d))))
  1. Create a 3D scatter plot using matplotlib:
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# Extract x, y, and z coordinates
x = points_3d[:, 0]
y = points_3d[:, 1]
z = points_3d[:, 2]

# Create the scatter plot
ax.scatter(x, y, z, c='b', marker='o', s=50)

# Customize the plot if needed
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
ax.set_title('3D Point Cloud')

plt.show()

This code will create a 3D scatter plot where each point from the 2D array is represented as a point in 3D space. You can adjust the appearance and customization of the plot as needed to fit your specific requirements.

user:

Can you encapsulate it in a function that only passes in a two-dimensional numpy array

chatgpt:

Certainly! You can encapsulate the code I provided earlier into a function that takes a 2D NumPy array as input and displays it as a 3D point cloud. Here's a function for that:

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

def plot_2d_array_as_3d_point_cloud(points_2d):
    # Assign a constant z-coordinate (e.g., 0) to all points
    points_3d = np.column_stack((points_2d, np.zeros(len(points_2d))))

    # Create a 3D scatter plot
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')

    # Extract x, y, and z coordinates
    x = points_3d[:, 0]
    y = points_3d[:, 1]
    z = points_3d[:, 2]

    # Create the scatter plot
    ax.scatter(x, y, z, c='b', marker='o', s=50)

    # Customize the plot if needed
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.set_title('3D Point Cloud')

    plt.show()

# Example usage:
points_2d = np.array([[1.0, 2.0],
                      [2.0, 3.0],
                      [3.0, 1.0],
                      [4.0, 4.0]])

plot_2d_array_as_3d_point_cloud(points_2d)

Now, you can call the plot_2d_array_as_3d_point_cloud function with your 2D NumPy array as an argument, and it will display the point cloud in a 3D plot.

然后测试发现,它给的代码,需要二维数组中每一行是一个点,这一行包含x,y,z坐标,所以我编写了一个转换的函数

def convertor(depth_arr):
    data = []
    for x in range(len(depth_arr)):
        for y in range(len(depth_arr[x])):
            data.append([x, y, depth_arr[x][y]])
    return np.array(data)

test.py 中修改

    cv2.imshow("Depth Viewer", depth_image)
    key = cv2.waitKey(1)
    if key == ord('q') or key == ESC_KEY:
        plot_2d_array_as_3d_point_cloud(convertor(depth_arr))
        break

测试发现,点太多了加载得很卡,所以对转换的函数进行了修改

def convertor(depth_arr):
    data = []
    for x in range(len(depth_arr) // 10):
        for y in range(len(depth_arr[x]) // 10):
            data.append([x * 10, y * 10, depth_arr[x * 10][y * 10]])
    return np.array(data)
test2.py

```python import numpy as np import matplotlib.pyplot as plt


​ def plot_2d_array_as_3d_point_cloud(points_2d): ​ # Assign a constant z-coordinate (e.g., 0) to all points ​ points_3d = np.column_stack((points_2d, np.zeros(len(points_2d)))) ​
​ # Create a 3D scatter plot ​ fig = plt.figure() ​ ax = fig.add_subplot(111, projection='3d') ​
​ # Extract x, y, and z coordinates ​ x = points_3d[:, 0] ​ y = points_3d[:, 1] ​ z = points_3d[:, 2] ​
# Create the scatter plot ax.scatter(x, y, z, c='b', marker='o', s=50)

    # Customize the plot if needed
    ax.set_xlabel('X')
    ax.set_ylabel('Y')
    ax.set_zlabel('Z')
    ax.set_title('3D Point Cloud')

    plt.show()


​ if name == 'main': ​ # Example usage: ​ points_2d = np.array([[1.0, 2.0], ​ [2.0, 3.0], ​ [3.0, 1.0], ​ [4.0, 4.0]]) ​
​ plot_2d_array_as_3d_point_cloud(points_2d)


​ def convertor(depth_arr): ​ data = [] ​ for x in range(len(depth_arr) // 10): ​ for y in range(len(depth_arr[x]) // 10): ​ data.append([x * 10, y * 10, depth_arr[x * 10][y * 10]]) ​ return np.array(data) ​ ```

最后显示的效果,感觉很好😊😄,能够看出对应的位置

depth_diagram

10.7

配置环境上,

由于需要安装 matplotlib>=3.2.2 ,而 jetson nano 上的 python 是 3.6.9 版本的, matplotlib 没有 aarch64 架构的 cp36 的 whl 文件,所以只能下载 .tar.gz 文件进行编译

我们下载了 matplotlib-3.3.4.tar.gz ,但在

sudo python3 setup.py install

时,产生了 Illegal struction 的报错,

查询相关信息,发现了这个问题

python - Jetson AGX Xavier python3 matplotlib 3.3.4 installation error - Stack Overflow

其中 RapidEdgeAI 的回答提到,可以尝试将 1.19.5 的 numpy 降级安装 1.19.4 的版本,在最终尝试了这个方法之后(之前试了很多方法但没用),最终成功安装了 matplotlib


在后续安装一些包时,不知为何总是会 Collecting numpy>=x.x.x ,即使已安装的 1.19.4 版本已经高于最低要求的版本,所以我开始查询直接忽略依赖安装包的方法

然后查到可以使用 --no-deps 选项来忽略安装依赖,最后发现可行直接安装了包

pip3 install scipy-1.5.4-cp36-cp36m-linux_aarch64.whl --no-deps

最后发现可行直接安装了 scipy 包

10.9

成功自动加载 pyorbbecsdk 的包

~/.bashrc 中最后添加上了基于官方文档中的测试命令修改的 sh 脚本

export PYTHONPATH=$PYTHONPATH:~/Desktop/pyorbbecsdk/install/lib/
# install udev rules
echo "1111" | sudo -S bash ~/Desktop/pyorbbecsdk/scripts/install_udev_rules.sh
echo "1111" | sudo -S udevadm control --reload-rules && echo "1111" | sudo -S udevadm trigger

原本的命令是

export PYTHONPATH=$PYTHONPATH:$(pwd)/install/lib/
sudo bash ./scripts/install_udev_rules.sh
sudo udevadm control --reload-rules && sudo udevadm trigger

最后测试成功自动添加了python环境变量,不会显示出 No module named 'pyorbbecsdk' 的报错信息


通讯部分由于之前没人负责写,所以我在火车站开始尝试写

由于需要使用 socket 包,所以我开始安装这个包,

但是 pip install socket 时却显示

Looking in indexes: https://mirrors.bfsu.edu.cn/pypi/web/simple/
ERROR: Could not find a version that satisfies the requirement socket (from versions: none)
ERROR: No matching distribution found for socket

所以搜索相关信息,发现需要改成 sockets

pip install sockets

然后安装成功


由于同学写出了 基于深度帧的数据分割桌面 的算法(是采用之前我提出的想法),大致是,先在深度帧中分割,然后在彩色帧中分割出对应的位置,

但我注意到,相机读取的深度帧的视角和彩色帧的视角不一样大,如果采用直接读取的深度帧和彩色帧,在分割时需要进行一定的转换

但运行 pyorbbecsdk\examples\depth_color_sync_align_viewer.py 能获取出深度帧和彩色帧结合在一起的图像,所以我根据这个文件的代码,获取到了对应了位置的深度帧和帧的图像,然后进行了分割算法的测试

最后测试的效果发现还不错

desk_segment


由于其他同学写的其他部分的功能,需要使用保存成文件的图像,

在写相应代码的时候,我发现可以将 numpy 数组直接保存成二进制文件来读写,速度就会稍微变快(深度帧和彩色帧都可以用 numpy 矩阵来存储)

new3.py
def main(argv):
    pipeline = Pipeline()
    config = Config()
    parser = argparse.ArgumentParser()
    parser.add_argument("-m", "--mode",
                        help="align mode, HW=hardware mode,SW=software mode,NONE=disable align",
                        type=str, default='HW')
    parser.add_argument("-s", "--enable_sync", help="enable sync", type=bool, default=True)
    args = parser.parse_args()
    align_mode = args.mode
    enable_sync = args.enable_sync
    try:
        profile_list = pipeline.get_stream_profile_list(OBSensorType.COLOR_SENSOR)
        color_profile = profile_list.get_default_video_stream_profile()
        config.enable_stream(color_profile)
        profile_list = pipeline.get_stream_profile_list(OBSensorType.DEPTH_SENSOR)
        assert profile_list is not None
        depth_profile = profile_list.get_default_video_stream_profile()
        assert depth_profile is not None
        print("color profile : {}x{}@{}_{}".format(color_profile.get_width(),
                                                   color_profile.get_height(),
                                                   color_profile.get_fps(),
                                                   color_profile.get_format()))
        print("depth profile : {}x{}@{}_{}".format(depth_profile.get_width(),
                                                   depth_profile.get_height(),
                                                   depth_profile.get_fps(),
                                                   depth_profile.get_format()))
        config.enable_stream(depth_profile)
    except Exception as e:
        print(e)
        return
    if align_mode == 'HW':
        config.set_align_mode(OBAlignMode.HW_MODE)
    elif align_mode == 'SW':
        config.set_align_mode(OBAlignMode.SW_MODE)
    else:
        config.set_align_mode(OBAlignMode.DISABLE)
    if enable_sync:
        try:
            pipeline.enable_frame_sync()
        except Exception as e:
            print(e)
    try:
        pipeline.start(config)
    except Exception as e:
        print(e)
        return
    while True:
        try:
            frames: FrameSet = pipeline.wait_for_frames(100)
            if frames is None:
                continue
            color_frame = frames.get_color_frame()
            if color_frame is None:
                continue
            # covert to RGB format
            color_image = frame_to_bgr_image(color_frame)
            if color_image is None:
                print("failed to convert frame to image")
                continue
            depth_frame = frames.get_depth_frame()
            if depth_frame is None:
                continue

            width = depth_frame.get_width()
            height = depth_frame.get_height()
            scale = depth_frame.get_depth_scale()

            depth_data = np.frombuffer(depth_frame.get_data(), dtype=np.uint16)
            depth_data = depth_data.reshape((height, width))
            depth_data = depth_data.astype(np.float32) * scale
            depth_image = cv2.normalize(depth_data, None, 0, 255, cv2.NORM_MINMAX, dtype=cv2.CV_8U)
            # depth_image = cv2.applyColorMap(depth_image, cv2.COLORMAP_JET)
            # overlay color image on depth image
            # depth_image = cv2.addWeighted(color_image, 0.5, depth_image, 0.5, 0)
            cv2.imshow("SyncAlignViewer ", depth_image)
            # cv2.imwrite("color_viewer.jpg", color_image)
            np.save("color_image", color_image)
            key = cv2.waitKey(1)
            my_seg(depth_data, color_image)
            output_data(depth_data)
            if key == ord('q') or key == ESC_KEY:
                break
        except KeyboardInterrupt:
            break
    pipeline.stop()


def output_data(depth_data):
    np.save("depth_data", depth_data)
    # np.savetxt("depth_data", depth_data)
    color_image = cv2.imread

if __name__ == "__main__":
    main(sys.argv[1:])

最后更新: 2023-10-21
创建日期: 2023-09-29

评论