3

I am just starting to learn LabVIEW. I want to get a threshold from my image in a python function and display the image in LabVIEW. But when the function returns the image, it gives an error in LabVIEW. I am sending the relevant code in Python and the LabVIEW program as an attachment. Thanks

import numpy as np
import cv2

def thershold(data):

    gray = np.array(data,dtype=np.uint8)
    ret, thresh1 = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)
    return np.array( thresh1, dtype=np.float64)

if __name__ == '__main__':
    data = cv2.imread('C:/Users/user00/Desktop/LabView/1120220711_151148.tiff', 1)
    thresh  = thershold(data)
    cv2.imshow('thresh1',thresh)
    cv2.waitKey(0)

enter image description here

enter image description here

kosist
  • 2,868
  • 2
  • 17
  • 30
Saberi
  • 41
  • 3
  • I don’t know or use Labview, but your `thresh1` is already a Numpy array so maybe you should just return that? Also, pay attention to what **type** of data Labview expects - does it want `float64` or `uint8`? If it wants float64, use `return thresh1.astype('np.float64')`. Also pay attention to the range Labview expects - is it 0..1 or 0..255 or something else? – Mark Setchell Jul 23 '22 at 08:15
  • Thankful The function works without problems in Python, but in labview, I tested both float64 and uint8 modes, unfortunately, the same error is displayed. In Python, it shows the threshold image in both modes. – Saberi Jul 23 '22 at 08:34
  • 3
    I think you use Python Node function in a wrong way, parameters do not match what the function expects. Please check documentation https://www.ni.com/docs/en-US/bundle/labview/page/glang/python_node.html, then look at the examples - they usually help – Mateusz Owczarek Jul 23 '22 at 09:09

1 Answers1

1

As the commenters on your post have suggested, it appears that the python code and LabVIEW code are expecting different types. When you perform the test just in Python the code adapts as required to show the image but the types need to match when passing between the two environments.

As per the OP's comment below, we need to pass a grayscale image and return an RGB image.

The grayscale image is easier as it is a 2D array of uint8 types. We can convert a Grayscale IMAQ image into the correct array type using IMAQ ImageToArray.vi.

When it comes to passing an RGB image back to LabVIEW we need to know the following:

  • In OpenCV an RGB image is a 2-dimensional image with multiple "channels". Each channel represents one of the colours and the OpenCV convention is to store the channels in the Blue-Green-Red channel order
  • In LabVIEW IMAQ RGB images are represented as a 2-dimensional image of unsigned 32-bit integers. The most significant byte is the Alpha channel which IMAQ cannot handle but is still stored. The next byte is the Red Channel, then the Green Channel and finally the least significant byte is the Blue Channel

We have two options - we can either format the image data before passing it from the Python side or we can take the Python image data as-is and transform it to the format LabVIEW/IMAQ needs in LabVIEW.

In The example code below I choose the latter (because I have more experience manipulating data in LabVIEW). Once theRGB image data is an array of U32 integers we can use the IMAQ ArrayToColorImage.vi to write the data to the IMAQ image.

The associated Python code is

import numpy as np
import cv2

def threshold(data):

    gray = np.array(data,dtype=np.uint8)
    # perform threshold operation
    ret, thresh1 = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY)

    #
    # create an RGB image to demonstrate output
    #
    height = 200
    width = 300

    rgb = np.zeros((height,width,3), np.uint8)
    # create RGB verticle stripes
    # note cv2 channels are arranged BGR
    # red stripe
    rgb[:,0:width//3] = (0,0,255)
    # green stripe
    rgb[:,width//3:2*width//3] = (0,255,0)
    # blue stripe
    rgb[:,2*width//3:width] = (255,0,0)

    # return rgb 3d-array
    return rgb

LabVIEW Code to Pass a Grayscale Image to Python and Return an RGB Image

Front Panel of the VI

Note - the labVIEW code is attached as a VI snippet so you should be able to drag it into a fresh LabVIEW Block-Diagram

Alternatively all the code is in this github gist

John
  • 1,313
  • 9
  • 21
  • Thank you for your help , Would it be possible for you to send me the "vi" file? @John – Saberi Jul 25 '22 at 09:02
  • If I want the input image to Labview to be of gray type, but the output image is an array of RGB, which is the contours drawn in Python by the corresponding function, what should I do? – Saberi Jul 25 '22 at 09:12
  • @Saberi - hopefully this answers your question. If it has, would you mark it as the answer please? – John Jul 28 '22 at 15:33
  • Hello No, unfortunately, this is not what I meant. Thanks for your help @john – Saberi Jul 30 '22 at 11:24
  • Can you answer the following 3 questions 1. Type of Image you want to load from disk (gray-scale or colour). 2. Type of Image your python code generates before it is passed out to LabVIEW. 3 Type of image you want to pass back to LabVIEW and display – John Jul 31 '22 at 07:57
  • 1. Our image is gray type. 2. The image becomes RGB in Python. 3. LabView shows the color image of Python output – Saberi Aug 03 '22 at 04:26
  • @Saberi - I am somewhat confused then. My code demonstrates passing a gray image from LabVIEW to python. The `gray` numpy array is this grayscale image in the python code. My python code then creates an RGB image which is passed out and displayed in LabVIEW. You would replace that section of python code which creates and RGB image with your code but then output the numpy array in the same way. I have assumed that all images use 256 colors hence are 1-byte per pixel. Could you explain how my code doesn't address the problem you are having? – John Aug 03 '22 at 17:52