basler / pypylon

The official python wrapper for the pylon Camera Software Suite
http://www.baslerweb.com
BSD 3-Clause "New" or "Revised" License
567 stars 207 forks source link

OutputPixelFormat is not supported by the image format converter #38

Closed terbed closed 6 years ago

terbed commented 6 years ago

Dear All,

I have a basler camera (acA1600-20uc) which supports the following PixelFormats:

BGR 8 BGRA 8 Bayer 12 Bayer 8 Mono 8 RGB 8

I want to process the captured images with opencv, so I convert the image with the converter. The only format the converter accepts is PixelType_BGR8packed otherwise I get this error: Traceback (most recent call last):

  File "/home/terbe/rppg-online-python/run_application.py", line 26, in <module>
    converter.OutputPixelFormat = pylon.PixelType_BGR12packed
  File "/home/terbe/anaconda2/lib/python2.7/site-packages/pypylon/pylon.py", line 6347, in SetOutputPixelFormat
    return _pylon.ImageFormatConverter_SetOutputPixelFormat(self, pxl_fmt)
_genicam.RuntimeException: The set output format (36700187) is not a supported by the image format converter. : RuntimeException thrown (file 'ImageFormatConverterImpl.h', line 400)

For my work it is important to get 12bit depth image. Is it possible somehow? I attach the modified sample code below:

'''
A simple Program for grabing video from basler camera and converting it to opencv img.
Tested on Basler acA1300-200uc (USB3, linux 64bit , python 3.5)

'''
from pypylon import pylon
import cv2
import time

# conecting to the first available camera
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice())
camera.Open()

camera.Width.Value = 1000
camera.Height.Value = 500
camera.OffsetX.Value = 200
camera.OffsetY.Value = 100
camera.ExposureTime.SetValue(10000)
camera.AcquisitionFrameRate.SetValue(20)

# Grabing Continusely (video) with minimal delay
camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
converter = pylon.ImageFormatConverter()

# converting to opencv bgr format
converter.OutputPixelFormat = pylon.PixelType_BGR12packed
converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned

while camera.IsGrabbing():
    startTime = time.time()
    grabResult = camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)

    if grabResult.GrabSucceeded():
        # Access the image data
        image = converter.Convert(grabResult)
        img = image.GetArray()
        cv2.namedWindow('title', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('title', img)
        k = cv2.waitKey(1)
        if k == 27:
            break
    grabResult.Release()

    runningTime = (time.time() - startTime)
    fps = 1.0/runningTime
    print "%f  FPS" % fps

# Releasing the resource    
camera.StopGrabbing()
cv2.destroyAllWindows()
thiesmoeller commented 6 years ago

Hi @terbed,

The conversion into a multibyte RGB format is supported, but not easily available at the moment:

a) the image format converter can be set up to use a RGB16packed format

you have to decide if you want your 12bit data lsb or msb aligned in the 16bit image

converter = pylon.ImageFormatConverter()

# converting to opencv bgr format
converter.OutputPixelFormat = pylon.PixelType_RGB16packed
converter.OutputBitAlignment = pylon.OutputBitAlignment_LsbAligned

As the Image type has no working automatic conversion between uint16 type and a numpy array you have to do it by hand:

        image = converter.Convert(grabResult)
        img = np.ndarray(buffer=image.GetBuffer(),shape= image.GetHeight(),image.GetWidth(),3),dtype=np.uint16)

This should solve your direct issue of working with 12bit color data.

terbed commented 6 years ago

hi @thiesmoeller,

First of all thank you for your reply! It works in this way indeed:

# converting to opencv bgr format
converter.OutputPixelFormat = pylon.PixelType_RGB16packed
converter.OutputBitAlignment = pylon.OutputBitAlignment_LsbAligned
bgr_img = frame = np.ndarray(shape=(img_height, img_width, 3), dtype=np.uint16)

.
.
.

        image = converter.Convert(grabResult)
        frame = np.ndarray(buffer=image.GetBuffer(), shape=(image.GetHeight(), image.GetWidth(), 3), dtype=np.uint16)
        bgr_img[:, :, 0] = frame[:, :, 2]
        bgr_img[:, :, 1] = frame[:, :, 1]
        bgr_img[:, :, 2] = frame[:, :, 0]

        cv2.namedWindow('Video', cv2.WINDOW_AUTOSIZE)
        cv2.imshow('Video', bgr_img*15)