Calc Results by Python
Function
This Step runs a user-defined script through Python and outputs the calculation results to Mech-Vision.
The characteristics of this Step are as follows:
-
Support multi-threading.
-
Load Python script in real time.
-
Support various data type conversions when transferring data between C++ and Python.
-
Support to display the Python’s log in the log panel of Mech-Vision.
Usage Scenario
When a custom calculation is required, this Step can be used to run the user-defined Python script and the workflow of the Steps can be simplified in the project.
Input and Output
-
Input: determined by the data type input in the Input Port(s) parameter.
-
Output: determined by the data type input in the Output Port(s) parameter.
You can specify the data type of the input/output port according to the data type of the prior or succeeding Steps’ input/output port. |
Installation and Usage
Installation
Python 3.6.8 is built into Mech-Vision, and thus this Step will use the built-in Python environment of the software. If there is any missing Python library when you use this Step, you need to install the library in the Mech-Vision’s built-in Python environment. The procedures for installation are as follows:
-
Open the command prompt window.
-
Use the CD command to go to the directory where Python is stored in Mech-Vision.
-
Type “python -m pip install Python name of the library” on the command line to install the missing Python library.
The two frequently-used Python libraries, NumPy and OpenCV, are built into Mech-Vision. |
Usage Instructions
After preparing the Python script, please follow the procedure below to use the Step. For detailed description of the parameters, please refer to Parameter Description.
-
Set the data type for the input and output ports. Enter the data type for Input Port(s) and Output Port(s) according to the data type of the prior or succeeding Steps’ input/output port.
-
Specify the file path of the Python script. Select the file path of the script to be loaded in the Script File Path parameter.
-
Set the name of the function to be called. Once the Script File Path has been specified, this Step will retrieve the function names in the script automatically, and you can select the name of the function to be called in the drop-down list of Func Name.
-
Run the Step.
|
From Mech-Vision 1.8.0, the execution mode of the “Calc Results by Python” Step is changed from serial to parallel (consistent with the effect of the threading module in Python). When calling camera APIs that do not support parallel execution within the script (such as enumerating cameras), it is necessary to add a lock at the location of that API call. |
Notes
Please pay attention to the following issues when you write the Python script and run the script in this Step.
Third-Party Library is Recommended
Because running a Python script in Mech-Vision differs from running the script in Python directly, some Python libraries could not be installed successfully or they cannot function properly after being installed, it is recommended to use third-party libraries.
Use the NumPy Library
The NumPy library is used to support some complicated formats of data. If a parameter type is ndarray, but the NumPy has not been imported, an error may occur. Therefore, you should add the import numpy statement at the beginning of the script.
Pay Attention to the Data Dimension when Writing the Script
When writing the Python script, please note the dimension of data corresponding to each port of the Step.
-
0 dimension by default: Image; Cloud(XYZ); Cloud(XYZ-Normal)
-
1 dimension by default: NumberList; BoolList; IndexList; StringList
-
2 dimensions by default: PoseList; Pose2DList; Size3DList
Use “[]” after the data type to add a dimension. For example, the data dimension of NumberList is 1, while the data dimension of NumberList[] is 2. |
Parameter Description
- Input Port(s)
-
Description: This parameter is used to specify the data type(s) of the input port(s). The input data types will be passed to the called function as parameters in the corresponding order.
Default value: null.
- Output Port(s)
-
Description: This parameter is used to specify the data type(s) of the output port(s). Data returned by the function will be returned to the Step in the corresponding order and will be parsed according to the corresponding data type.
Default value: null.
The currently supported data types are as follows:
Port Type |
Example |
PoseList |
[[10, 20, 30, 0.951, 0.255, 0.168, 0.045]], [10, 20, 30, 0.951, 0.255, 0.168, 0.045]]
|
Pose2DList |
[[0, 0, 0]], [2, 0, 120]]
|
NumberList |
[1.1, 2, 999.9, -22] |
StringList |
['string_1', 'string_2', 'string_3'] |
Image |
Image data |
Cloud(XYZ) |
Point cloud data |
Cloud(XYZ-Normal) |
Point cloud data with normals |
Cloud(XYZ-RGB) |
Data of textured point cloud |
Size3DList |
[[2.5, 5, 0.001]], [6, 5, 0.02]]
|
IndexList |
[45, 10, 90] |
BoolList |
[True, False, True] |
- Script File Path
-
Description: This parameter is used to select the file path of the script to be loaded.
Default value: Null.
- Func Name
-
Description: This parameter is used to set the name of the function to be called.
Default value: null.
Python Example Programs
To facilitates the learning and utilizing of this Step, some Python programs are provided in the following section to help you get familiar with the Step port type.
Getting Started
Output Data of One Type with Python Script
The function that outputs data of one type is defined in the program below. Please refer to Usage Instructions to call this function in the Step.
def get_doublelist():
return [1.1,22,3.3]
The Mech-Vision project corresponding to this function is shown below. You can double-click the dataflow corresponding to the output port to check the output result.
Output Data of Multiple Types with Python Script
The function that outputs data of multiple types s defined in the program below. Please refer to Usage Instructions to call this function in the Step.
def example_of_basic_portTypes():
numList = [1.1, 2, 999.9, -22]
indexList = [45, 10, 90]
boolList = [True, False, True]
strList = ['string_1', 'string_2', 'string_3']
poseList = [[10, 20, 30, 0.951, 0.255, 0.168, 0.045], [10, 20, 30, 0.951, 0.255, 0.168, 0.045]]
pose2dList = [[0, 0, 0], [2, 0, 0.785]]
size3dList = [[2.5, 5, 0.001], [6, 5, 0.02]]
return numList, indexList, boolList, strList, poseList, pose2dList, size3dList
The Mech-Vision project corresponding to this function is shown below. You can double-click the dataflow corresponding to the output ports to check the output results.
Process Data with Two “Calc Results by Python” Steps
The function to output the list of numerical values is defined in Program 1. The function to calculate the sum of values within each numerical list is defined in Program 2.
Please refer to Usage Instructions to use the following programs, connect Steps, and calculate the sum of the input numerical lists.
Program 1:
def get_numberlist_1():
return [[1, 2, 3],[4,5,6]]
Program 2:
def cal_number_list(nums_list):
sums = [align="center"]
for nums in nums_list:
sum = 0
for num in nums:
sum += num
sums.append(sum)
return [sums]
The Mech-Vision project corresponding to this function is shown below. You can double-click the dataflow corresponding to the output ports to check the output results.
Process Data with Multiple “Calc Results by Python” Steps
The function to output the list of numerical values is defined in Program 1. The function to output lists of Booleans is defined in Program 2. In program 3, the value “9999” is added to the numerical value, and a “False” is added to the list of Booleans, and the new list of numerical values and list of Booleans will be output.
Please refer to Usage Instructions to use the following programs in the Step to process the input data.
Program 1:
def get_doublelist():
return [1.1,22,3.3]
Program 2:
def get_bool_list():
return [[True,False],[True,True],[False,False]]
Program 3:
def print_multi_values(numberList, boolList):
numberList.append(9999)
boolList.append(False)
return numberList, boolList
The Mech-Vision project corresponding to this function is shown below. You can double-click the dataflow corresponding to the output ports to check the output results.
Application Examples
Saving Abnormal Data Generated During Project Execution
In actual applications, various errors may occur in the project. You can use the custom Python script together with the Data Storage feature in Mech-Vision to save the abnormal data for troubleshooting, thus improving the stability of the vision system.
The detailed instructions are as follows.
-
Enable the Data Storage feature.
Enable Save data and parameters in Mech-Vision Project Assistant. If errors occur when the project executes, the raw data will be save under Project folder/data/error_data.
-
Write the Python script.
A Python example program that determines whether the pose result output by the “3D Matching” Procedure is null is as follows:
def abnormal_output_detection(outputs): if len(outputs) == 0: raise Exception("NO RESULT!!!") else: pass
-
Please refer to Usage Instructions to use the above program in the Step, and connect the Step after “3D Matching”.
After running the project, if the pose result output by “3D Matching” is null, an error message will pop up, and the abnormal data will be saved under Project folder/data/error_data.
Generate Pseudo Colored Point Cloud Based on Z Values of the Input Point Cloud
When the output point cloud does not have the textured information, you can use the custom Python script to generate pseudo colored point cloud based on the Z values of the input point cloud for better visualization of the output.
The processing process can be summarized as follows:
Firstly, the Z values will be mapped to values between 0 to 255 to obtain the grayscale values. Then OpenCV will be used to map the grayscale values to RGB values and therefore the pseudo colored point cloud can be generated.
The example program is as follows:
import math
import cv2
import numpy as np
def generate_color_point_could_by_depth(point_cloud):
x = point_cloud[:, 0]
y = point_cloud[:, 1]
z = point_cloud[:, 2]
z_min = np.min(z)
z_max = np.max(z)
if math.isclose(z_max - z_min, 0):
return np.column_stack((x, y, z, np.full(z.shape, 0xFFFFFFFF, np.uint32).view(np.float32)))
color = 255 * (z - z_min) / (z_max - z_min)
color = cv2.applyColorMap(color.astype(np.uint8), cv2.COLORMAP_JET)
color = np.squeeze(color).astype(np.uint32)
color = (0xFF000000 | (color[:, 0] << 16) | (color[:, 1] << 8) | color[:, 2]).view(np.float32)
return np.column_stack((x, y, z, color))