IC-Imaging-Control-Samples icon indicating copy to clipboard operation
IC-Imaging-Control-Samples copied to clipboard

Horizontal black lines on image

Open kmcgrathgenerate opened this issue 2 years ago • 4 comments

I am using a DMK 37BUX287 using TISGrabber.py in python. I am having black horizontal lines show up on every image using SnapImage() that I believe is coming right from the API. Was hoping to track down the issue here.

Here is relevant code:

Camera INIT:

def init_camera(self):
        self.hGrabber = ic.IC_CreateGrabber()
        self.width = 720
        self.height = 100
        ic.IC_OpenVideoCaptureDevice(self.hGrabber, tis.T("DMK 37BUX287"))
        ic.IC_SetVideoFormat(self.hGrabber, tis.T("Y800 ({width}x{height})".format(width=self.width, height=self.height)))
        ic.IC_SetFrameRate(self.hGrabber, ctypes.c_float(5000.0))

Snapping an Image:

    def snap_image(self):
        if ic.IC_SnapImage(self.hGrabber, 1) == tis.IC_SUCCESS:
            # Declare variables of image description
            Width = ctypes.c_long()
            Height = ctypes.c_long()
            BitsPerPixel = ctypes.c_int()
            colorformat = ctypes.c_int()

            # Query the values of image description
            ic.IC_GetImageDescription(self.hGrabber, Width, Height,
                                        BitsPerPixel, colorformat)

            # Calculate the buffer size
            bpp = int(BitsPerPixel.value / 3)
            buffer_size = Width.value * Height.value * bpp

            # Get the image data
            imagePtr = ic.IC_GetImagePtr(self.hGrabber)

            imagedata = ctypes.cast(imagePtr,
                                    ctypes.POINTER(ctypes.c_ubyte *
                                                    buffer_size))

            # Create the numpy array
            self.cv_img = np.ndarray(buffer=imagedata.contents,
                                     dtype=np.uint8,
                                     shape=(Height.value,
                                            Width.value,
                                            1))
            self.cv_img = np.squeeze(self.cv_img, axis=2)

The image looks like:

image

Another thing to note: I also notice that the return of the "IC_GetImageDescription" function has the bits per pixel coming back as 24, I am shrinking that to 8 (divide by 3)

Any idea where the black lines are coming from?

kmcgrathgenerate avatar Jun 30 '22 17:06 kmcgrathgenerate

I believe I may have found the issue. I am using a DisplayLink docking station that may be maxed out on data output. I have 2 4K monitors with the DMK camera into the USB3.0 port. I brought this camera to another setup and the horizontal lines were not present.

kmcgrathgenerate avatar Jun 30 '22 19:06 kmcgrathgenerate

Question 1) I suggest to set a valid frame rate, because the camera wont deliver 5000 fps at 720x100 resolution. You may use IC Capture to see, what is the maximum frame rate offered at this resolution. Then you may use somewhat slower frame rate and check the images. The posted image does not look like the usual USB (2) Bandwidth issues, the pattern is far to regular. You may try with IC Capture too and compare the images.

Question 2) RGB24 is the default pixel format in memory. Please call ic.IC_SetFormat(hGrabber, tis.SinkFormats.Y800) before starting the pipeline. Then you will have one byte per pixel gray scale in memory, as provided by the camera.

Stefan

TIS-Stefan avatar Jul 01 '22 07:07 TIS-Stefan

@TIS-Stefan Thank you for the quick response. I set the video format based on your response to question 2, not sure if you were expecting this but, the horizontal lines are all gone now.

image

In the function call, ic.IC_SetVideoFormat(self.hGrabber, tis.T("Y800 ({width}x{height})".format(width=self.width, height=self.height))), it appears you set the Y800 here, if I remove this Y800 from the string, the width/height is not set, so it seems like it is needed. I am curious why its in the SetVideoFormat call but doesn't seem to set the color format.

Also in the same vein, is there a better way to change the width/height on the fly other than stopping the live feed, setting the video format, and turning it back on?

kmcgrathgenerate avatar Jul 01 '22 12:07 kmcgrathgenerate

if I remove this Y800 from the string, the width/height is not set, so it seems like it is needed. I am curious why its in the SetVideoFormat call but doesn't seem to set the color format.

Yes, "Y800" is needed, otherwise we do not know, which pixel format to set in the camera. The default format in the sink, which means the memory in the computer, is RGB24. That means, the incoming Y800 of the camera is converted to RGB24 internally. But the pixel format in memory can be changed to Y800 by ic.IC_SetFormat(hGrabber, tis.SinkFormats.Y800) before starting the live stream. Y800 means one byte per pixel gray scale.

Also in the same vein, is there a better way to change the width/height on the fly other than stopping the live feed, setting the video format, and turning it back on?

No, because the memory allocations in the DirectShow filter graph must be done and this is possible only by stopping and starting it. Same is valid for the camera. It must be stopped too, in order to change the video format and frame rate.

TIS-Stefan avatar Jul 04 '22 08:07 TIS-Stefan