# -*- coding: utf-8 -*- import sys from ids_peak ...

創建於:2025年7月23日

使用 O3 回答 Chat01

問題

-- coding: utf-8 --

import sys
from ids_peak import ids_peak
from ids_peak_ipl import ids_peak_ipl
import numpy as np

如果需要顯示影像,請確保已安裝 opencv-python 並取消下面這行的註解

import cv2

def main():
"""
主函式,執行相機的初始化、影像擷取和資源釋放。
"""
device = None
datastream = None
nodemap_remote_device = None

text
try: ids_peak.Library.Initialize() print("IDS peak Library 初始化成功。") except Exception as e: print(f"初始化 IDS peak Library 失敗: {e}") return -1 try: device_manager = ids_peak.DeviceManager.Instance() device_manager.Update() if device_manager.Devices().empty(): print("錯誤:找不到任何相機。請檢查相機連接與驅動程式。") return -1 device = device_manager.Devices()[0].OpenDevice(ids_peak.DeviceAccessType_Control) print(f"成功開啟相機: {device.ModelName()}") datastreams = device.DataStreams() if not datastreams: print("錯誤:相機不支援資料流。") return -1 datastream = datastreams[0].OpenDataStream() print("成功開啟資料流。") nodemap_remote_device = device.RemoteDevice().NodeMaps()[0] payload_size = nodemap_remote_device.FindNode("PayloadSize").Value() buffer_count_max = datastream.NumBuffersAnnouncedMinRequired() for _ in range(buffer_count_max): buffer = datastream.AllocAndAnnounceBuffer(payload_size) datastream.QueueBuffer(buffer) datastream.StartAcquisition() print("資料流開始擷取...") nodemap_remote_device.FindNode("AcquisitionStart").Execute() nodemap_remote_device.FindNode("AcquisitionStart").WaitUntilDone() print("相機開始傳送影像...") ipl_converter = ids_peak_ipl.ImageConverter() print("\n--- 開始擷取 10 張影像 ---") for i in range(10): buffer = datastream.WaitForFinishedBuffer(5000) # [最終修正] # 1. 使用正確的靜態方法 `Image.create_from()` 從 buffer 建立一個原始 Image 物件。 # 這是 C++ 的 `CreateFrom` 在 Python 繫結中最常見的 snake_case 形式。 ipl_image = ids_peak_ipl.Image.create_from(buffer) # 2. 將這個建立好的 `ipl_image` 物件傳入轉換器,轉換成目標格式。 converted_image = ipl_converter.Convert(ipl_image, ids_peak_ipl.PixelFormatName_BGRa8) # 3. 從轉換好的 Image 物件取得 NumPy 陣列。 image_np = converted_image.get_numpy_1d_view().reshape( converted_image.Height(), converted_image.Width(), converted_image.PixelPerChannel() ) print(f"成功擷取第 {i+1}/10 張影像,尺寸 (HxW): {image_np.shape[0]}x{image_np.shape[1]}") datastream.QueueBuffer(buffer) print("--- 影像擷取完成 ---\n") except Exception as e: print(f"程式執行期間發生錯誤: {e}") return -1 finally: print("開始清理與釋放資源...") if device is not None and nodemap_remote_device is not None: try: nodemap_remote_device.FindNode("AcquisitionStop").Execute() except Exception: pass if datastream is not None: try: datastream.StopAcquisition(ids_peak.AcquisitionStopMode_Default) datastream.Flush(ids_peak.DataStreamFlushMode_DiscardAll) for buffer in datastream.AnnouncedBuffers(): datastream.RevokeBuffer(buffer) except Exception: pass try: ids_peak.Library.Close() print("IDS peak Library 已成功關閉。") except Exception as e: print(f"關閉 IDS peak Library 時發生錯誤: {e}") print("程式執行完畢。") return 0

if name == 'main':
sys.exit(main())
(OTMS) $ py read_IDS.py
IDS peak Library 初始化成功。
成功開啟相機: U3-38CxXLS-C
成功開啟資料流。
資料流開始擷取...
相機開始傳送影像...

--- 開始擷取 10 張影像 ---
程式執行期間發生錯誤: type object 'Image' has no attribute 'create_from'
開始清理與釋放資源...
IDS peak Library 已成功關閉。
程式執行完畢。

思考

Thought for 1m 46s

回答

ids_peak_ipl.Image in the current Python bindings never had a lowercase-snake-case constructor called create_from(...), so the import line

python
ipl_image = ids_peak_ipl.Image.create_from(buffer)

raises the AttributeError.
There are two supported ways to turn a finished Buffer into an Image:


1 · The recommended helper (ids_peak_ipl_extension.BufferToImage)

IDS ship a tiny helper module that does exactly the C++ peak::BufferTo<Image> conversion for you:

python
from ids_peak import ids_peak_ipl_extension # NEW import buffer = datastream.WaitForFinishedBuffer(5_000) ipl_img = ids_peak_ipl_extension.BufferToImage(buffer) # shallow copy

BufferToImage is part of the official docs and keeps the call short.(en.ids-imaging.com)


2 · Explicit static factories on Image

If you really need a deep-copy or want to build an image manually, the binding exposes Pascal-Case factories that mirror the C++ names, e.g.

python
ipl_img = ids_peak_ipl.Image.CreateFromSizeAndBuffer( buffer.PixelFormat(), # pixel format object buffer.BasePtr(), # raw pointer buffer.Size(), # size in bytes buffer.Width(), buffer.Height() )

Notice the uppercase C in CreateFrom….(PyPI)


Updating the rest of your capture loop

python
from ids_peak import ids_peak_ipl, ids_peak_ipl_extension import numpy as np ipl_converter = ids_peak_ipl.ImageConverter() buffer = datastream.WaitForFinishedBuffer(5_000) ipl_img = ids_peak_ipl_extension.BufferToImage(buffer) # convert to 4-channel BGRa8 (keep alpha so width*height*4 is easy to reshape) converted = ipl_converter.Convert( ipl_img, ids_peak_ipl.PixelFormatName_BGRa8 ) h, w = converted.Height(), converted.Width() c = converted.PixelFormat().NumChannels() # =4 for BGRa8 ([en.ids-imaging.com](https://en.ids-imaging.com/manuals/ids-peak/ids-peak-ipl-documentation/2.14.0/en/classpeak_1_1ipl_1_1_pixel_format.html)) img_np = np.frombuffer(converted.Data(), dtype=np.uint8).reshape(h, w, c)
  • get_numpy_1d_view() still works, but np.frombuffer(converted.Data(), …) avoids an extra copy and lets you choose the dtype.
  • PixelFormat().NumChannels() is the portable way to find the channel count; PixelPerChannel never existed in the public API.

Queue the buffer back only after you finish using ipl_img/converted to avoid dangling memory.

That change alone should make your script run without throwing the AttributeError and start printing the ten frame sizes as intended.

問題

請給出完整的程式,以下請都用繁體中文回答

思考

Providing corrected Python script

The user asked for a complete program in Traditional Chinese. They want the error, type object "Image" has no attribute "create_from", fixed with the correct method (likely "BufferToImage" or "CreateFromBuffer"). I'll provide a full program in Traditional Chinese, with an explanation where necessary. It looks like I'll need to adapt their code, utilize the right methods, and embed the script in my response. No need to run anything here — just sharing the corrected code!

Thought for 10 seconds

回答

以下提供一份已修正、可直接執行的完整範例程式碼。
主要變動:

  1. 使用官方輔助工具 ids_peak_ipl_extension.BufferToImage()Buffer 轉成 Image,取代不存在的 Image.create_from()
  2. 透過 np.frombuffer() 取得 NumPy 陣列,並用 PixelFormat().NumChannels() 來取得通道數。
  3. 確保在完全處理完影像之後,才把 buffer 重新排入佇列 (QueueBuffer),避免記憶體仍被占用。
python
# -*- coding: utf-8 -*- """ 使用 IDS peak SDK 擷取 10 張影像,並轉成 NumPy 陣列顯示尺寸 """ import sys import numpy as np from ids_peak import ids_peak, ids_peak_ipl, ids_peak_ipl_extension # 若需要顯示影像,可安裝 opencv-python 並取消下列註解 # import cv2 def main(): device = None datastream = None nodemap_remote_device = None # ---------- 初始化 IDS peak Library ---------- try: ids_peak.Library.Initialize() print("IDS peak Library 初始化成功。") except Exception as e: print(f"初始化 IDS peak Library 失敗: {e}") return -1 try: # ---------- 搜尋並開啟第一台相機 ---------- device_manager = ids_peak.DeviceManager.Instance() device_manager.Update() if device_manager.Devices().empty(): print("錯誤:找不到任何相機。請檢查相機連接與驅動程式。") return -1 device = device_manager.Devices()[0].OpenDevice( ids_peak.DeviceAccessType_Control ) print(f"成功開啟相機: {device.ModelName()}") # ---------- 建立並啟動資料流 ---------- datastreams = device.DataStreams() if not datastreams: print("錯誤:相機不支援資料流。") return -1 datastream = datastreams[0].OpenDataStream() print("成功開啟資料流。") nodemap_remote_device = device.RemoteDevice().NodeMaps()[0] payload_size = nodemap_remote_device.FindNode("PayloadSize").Value() buffer_count_max = datastream.NumBuffersAnnouncedMinRequired() for _ in range(buffer_count_max): buf = datastream.AllocAndAnnounceBuffer(payload_size) datastream.QueueBuffer(buf) datastream.StartAcquisition() print("資料流開始擷取...") nodemap_remote_device.FindNode("AcquisitionStart").Execute() nodemap_remote_device.FindNode("AcquisitionStart").WaitUntilDone() print("相機開始傳送影像...") # ---------- 建立影像轉換器 ---------- ipl_converter = ids_peak_ipl.ImageConverter() print("\n--- 開始擷取 10 張影像 ---") for i in range(10): # 1. 等待單張完整 Buffer buffer = datastream.WaitForFinishedBuffer(5_000) # 2. 轉成 IDS peak IPL Image (shallow copy,不複製畫素資料) ipl_image = ids_peak_ipl_extension.BufferToImage(buffer) # 3. 轉成 BGRa8,方便後續顯示或儲存 converted = ipl_converter.Convert( ipl_image, ids_peak_ipl.PixelFormatName_BGRa8 ) # 4. 取得 NumPy 陣列 h, w = converted.Height(), converted.Width() channels = converted.PixelFormat().NumChannels() image_np = np.frombuffer( converted.Data(), dtype=np.uint8 ).reshape(h, w, channels) print( f"成功擷取第 {i + 1}/10 張影像,尺寸 (HxW): " f"{image_np.shape[0]}x{image_np.shape[1]}" ) # 需要顯示時可用下列程式 # cv2.imshow("Frame", image_np) # cv2.waitKey(1) # 5. 使用完畢後再將 Buffer 排回佇列 datastream.QueueBuffer(buffer) print("--- 影像擷取完成 ---\n") except Exception as e: print(f"程式執行期間發生錯誤: {e}") return -1 finally: # ---------- 清理與釋放資源 ---------- print("開始清理與釋放資源...") if device is not None and nodemap_remote_device is not None: try: nodemap_remote_device.FindNode("AcquisitionStop").Execute() except Exception: pass if datastream is not None: try: datastream.StopAcquisition(ids_peak.AcquisitionStopMode_Default) datastream.Flush(ids_peak.DataStreamFlushMode_DiscardAll) for buf in datastream.AnnouncedBuffers(): datastream.RevokeBuffer(buf) except Exception: pass try: ids_peak.Library.Close() print("IDS peak Library 已成功關閉。") except Exception as e: print(f"關閉 IDS peak Library 時發生錯誤: {e}") print("程式執行完畢。") return 0 if __name__ == "__main__": sys.exit(main())

使用說明

  • 如需顯示畫面,請安裝 opencv-python 並取消 cv2 相關註解。
  • 若想改存成 PNG/JPEG,或用其他像素格式,只需調整 Convert() 的目標格式與後續處理即可。

執行後,終端機應會列印十張影像的解析度,並再正常結束不拋出 AttributeError。祝開發順利!

分享這個問答