scikit-image Analysis & Contour Extraction (GbE-2 / Python)
Steps for creating a program that uses the common module puclib.py created in HelloWorld to perform scientific-computing-grade image analysis (thresholding and contour extraction) with scikit-image (skimage) and matplotlib on an image captured from the GbE-2, and saves the results.
-
Create the script
In the same folder as
puclib.py, creategbe2_skimage_single_process.pyand write the following code.gbe2_skimage_single_process.py from ctypes import c_uint32, c_ushort, c_ubyte, c_void_p, byrefimport numpy as npimport matplotlib.pyplot as pltfrom skimage import filters, measure# Import from the common module puclib.pyfrom puclib import (load_sdk, PUC_SUCCEEDED, PUC_DETECT_TARGET_GBE2,PUC_Q_COUNT, PUC_DETECT_FILTER, PUC_DETECT_INFO, PUC_XFER_DATA_INFO)def main():print("Starting INFINICAM GbE-2 scikit-image analysis sample...")# 1. Load and initialize the SDKpuclib = load_sdk()if puclib.PUC_Initialize() != PUC_SUCCEEDED:print("Error: Failed to initialize the SDK.")return# 2. Search for and open the devicedetect_filter = PUC_DETECT_FILTER(nDeviceTypeFlags=PUC_DETECT_TARGET_GBE2)detect_info = PUC_DETECT_INFO()if puclib.PUC_DetectDevice2(byref(detect_filter), byref(detect_info)) != PUC_SUCCEEDED or detect_info.nDeviceCount == 0:print("Error: No GbE-2 camera was found.")returnh_device = c_void_p()if puclib.PUC_OpenDevice2(0, byref(h_device)) != PUC_SUCCEEDED:print("Error: Failed to open the device.")return# 3. Retrieve the resolution, quantization table, and transfer sizewidth, height = c_uint32(), c_uint32()puclib.PUC_GetResolution(h_device, byref(width), byref(height))w, h = width.value, height.valueq_vals = (c_ushort * PUC_Q_COUNT)()puclib.PUC_GetQuantization2(h_device, q_vals)xfer_data_size = c_uint32()puclib.PUC_GetXferDataSize(h_device, byref(xfer_data_size))print(f"Resolution: {w} x {h} pixels")# 4. Allocate bufferscomp_buffer = (c_ubyte * xfer_data_size.value)()line_bytes = (w + 3) & ~3 # 4-byte boundary alignmentdecoded_buffer = (c_ubyte * (line_bytes * h))()# 5. Perform the single-frame capturexfer_info = PUC_XFER_DATA_INFO()xfer_info.pData = comp_bufferxfer_info.nDataSize = xfer_data_size.valueprint("Capturing one frame...")if puclib.PUC_GetSingleXferData(h_device, byref(xfer_info)) == PUC_SUCCEEDED:# 6. Decode processingret = puclib.PUC_DecodeData(decoded_buffer, 0, 0, w, h, line_bytes, comp_buffer, q_vals)if ret == PUC_SUCCEEDED:# 7. Convert into a NumPy arrayimg = np.ctypeslib.as_array(decoded_buffer).reshape((h, line_bytes))[:, :w]# 8. Analysis processing with scikit-image# Determine an automatic threshold that maximizes between-class variance using Otsu's methodthresh = filters.threshold_otsu(img)binary_img = img > thresh# Detect contours on the binarized image using a marching-squares-based algorithmcontours = measure.find_contours(binary_img, 0.5)# 9. Draw and plot the analysis images with Matplotlibfig, ax = plt.subplots(1, 2, figsize=(10, 5))# Left: original imageax[0].imshow(img, cmap='gray')ax[0].set_title('Original Image')ax[0].axis('off')# Right: binarized image with the extracted contour lines overlaid (in red)ax[1].imshow(binary_img, cmap='gray')for contour in contours:ax[1].plot(contour[:, 1], contour[:, 0], linewidth=1.5, color='red')ax[1].set_title(f'Otsu Thresholding & Contours (Threshold: {thresh:.1f})')ax[1].axis('off')plt.tight_layout()# Savefilename = "skimage_analysis_result.png"plt.savefig(filename, bbox_inches='tight', dpi=150)print(f"SUCCESS: Saved the analysis result plot ({filename})")# Displayplt.show()else:print(f"Error: Failed to decode the image data. ErrorCode: {ret}")else:print("Error: Failed to retrieve the image data.")# 10. Closepuclib.PUC_CloseDevice(h_device)if __name__ == "__main__":main() -
Run the script
Terminal window python gbe2_skimage_single_process.pyWhen run, a Matplotlib graph window opens showing the original image on the left, and on the right the binarized image split at the Otsu threshold along with the detected contour lines (in red). Closing the window saves
skimage_analysis_result.pngin the current directory.
scikit-image Analysis Highlights
Section titled “scikit-image Analysis Highlights”1. Automatic thresholding (filters.threshold_otsu)
Section titled “1. Automatic thresholding (filters.threshold_otsu)”From the image’s histogram, a single threshold is statistically determined that best separates the foreground (subject) from the background. This is extremely powerful for automatic object-region extraction in environments without fixed brightness.
2. High-precision contour extraction (measure.find_contours)
Section titled “2. High-precision contour extraction (measure.find_contours)”Rather than working pixel by pixel, this interpolates along the continuity of boundaries to obtain contour lines as precise 2D coordinate lists. It is useful as a preprocessing step for measuring object area, perimeter, circularity, and other instrumentation or shape-analysis tasks.
