最近有接触过一丢丢VM4.3的模块开发. 一直有把python图像处理部分模块移植进来的打算 不过时间不够没来得及折腾.偶尔发现4.4支持py脚本 于是拿来折腾.一下午.
发现4.4支持python脚本,好开心.
首先安装VM4.4 注意一定要是4.4
打开后拖了一个模块.
但是发现import numpy import cv2 都报错.
python没有这些怎么玩? 咱好歹自学过几天python 不能放弃吧?
于是抱着试一试的态度?
开始以为路径是
C:\Program Files\VisionMaster4.4.0\Applications\Module(sp)\x64\Logic\PyShellModule
后来搜索感觉是这里:
C:\Program Files\VisionMaster4.4.0\Applications\ModuleProxy\x64
python.exe
C:\Program Files\VisionMaster4.4.0\Applications\ModuleProxy\x64\Scripts
pip.exe
补充一下:
C:\Program Files\VisionMaster4.4.0\Applications\ModuleProxy\x64\Scripts
这个目录是空的 需要双击执行get-pip.py等待文件下载完毕 里面才会出现 pip.exe等文件
好了,在这里按住shift右击 >>在此处打开powershell窗口 输入cmd
然后 尝试性的在此文件夹里 pip install numpy 当运行 import numpy as np 发现已经不报错了.
好了 现在直接在这个窗口:安装
pip install numpy
pip install opencv-python
pip install opencv-contrib-python
pip install pillow
pip install matplotlib
pip install numpy pillow opencv-python opencv-contrib-python matplotlib
# 我暂时只需要这么多 够用 你也可以安装别的
当然halcon装不了:强制安装也会报错:如下所示:
C:\Program Files\VisionMaster4.4.0\Applications\ModuleProxy\x64\Scripts>pip install mvtec-halcon==23050
ERROR: Ignored the following versions that require a different python version: 20110.0.0 Requires-Python >=3.8; 20110.0.1 Requires-Python >=3.8; 20111.0.0 Requires-Python >=3.8; 20111.0.1 Requires-Python >=3.8; 20112.0.0 Requires-Python >=3.8; 20113.0.0 Requires-Python >=3.8; 20114.0.0 Requires-Python >=3.8; 21050.0.0 Requires-Python >=3.8; 21110.0.0 Requires-Python >=3.8; 22050.0.0 Requires-Python >=3.8; 22110.0.0 Requires-Python >=3.8; 22110.0.1 Requires-Python >=3.8; 22111.0.0 Requires-Python >=3.8; 22111.0.1 Requires-Python >=3.8; 22112.0.0 Requires-Python >=3.8; 22112.0.1 Requires-Python >=3.8; 22113.0.1 Requires-Python >=3.8; 23050.0.0 Requires-Python >=3.8; 23110.0.0 Requires-Python >=3.8; 23110.0.1 Requires-Python >=3.8; 24050.0.0 Requires-Python >=3.8; 24111.0.0 Requires-Python >=3.8
ERROR: Could not find a version that satisfies the requirement mvtec-halcon==23050 (from versions: none)
ERROR: No matching distribution found for mvtec-halcon==23050
意味着必须3.8才能安装python版的halcon实在是非常遗憾. 官方能不能把你python版本升级到3.8呢?????????? 卡一个版本 气死人. 这个后面再想想别的办法.试试看能不能补救. 实在不行只能pythonnet 用halcon的.net接口了. 或者加强反馈等官方更新.
哈哈:
接下来又遇到难题:
官方文档只介绍输入输出图像的结构体: 没有示例程序.难搞.
结构体定义如下:
# 图像数据
class ImageData:
def __init__(self):
self.width = None
self.height = None
self.pixel_format = None
self.buffer = None
self.dataLen = None
其他类型 数据结构比较简单 见名知意: 好吧还是放出来吧:
# 路径 文件名
#C:\Program Files\VisionMaster4.4.0\Applications\Module(sp)\x64\Logic\PyShellModule
#组合数据类型字段定义.py
# ROI圆环
class RoiAnnulus:
def __init__(self):
self.center_x = None
self.center_y = None
self.inner_radius = None
self.outer_radius = None
self.start_angle = None
self.angle_extend = None
# 圆
class Circle:
def __init__(self):
self.radius = None
self.center_x = None
self.center_y = None
# 椭圆
class ELLIPSE:
def __init__(self):
self.center_x = None
self.center_y = None
self.major_radius = None
self.minor_radius = None
self.angle = None
# 位置修正信息
class Fixture:
def __init__(self):
self.init_point_x = None
self.init_point_y = None
self.init_angle = None
self.init_scale_x = None
self.init_scale_y = None
self.run_point_x = None
self.run_point_y = None
self.run_angle = None
self.run_scale_x = None
self.run_scale_y = None
# 图像数据
class ImageData:
def __init__(self):
self.width = None
self.height = None
self.pixel_format = None
self.buffer = None
self.dataLen = None
# 直线
class Line:
def __init__(self):
self.start_point_x = None
self.start_point_y = None
self.end_point_x = None
self.end_point_y = None
# 点
class Point:
def __init__(self):
self.point_x = None
self.point_y = None
# 轮廓
class PointSet:
def __init__(self):
self.buffer = None
self.dataLen = None
# 矩形
class Rect:
def __init__(self):
self.rect_x = None
self.rect_y = None
self.width = None
self.height = None
# Box
class RoiBox:
def __init__(self):
self.center_x = None
self.center_y = None
self.width = None
self.height = None
self.angle = None
# 多边形
class RoiPolygon:
def __init__(self):
self.point_num = None
self.point_x = None
self.point_y = None
# 圆环
class Annulus:
def __init__(self):
self.center_x = None
self.center_y = None
self.inner_radius = None
self.outer_radius = None
self.start_angle = None
self.angle_extend = None
直接上程序: 自己摸索的 输入输出 官方可没有示例 噢
# coding: utf-8
from ioHelper import *
# pip install opencv-python
# pip install numpy
import os,sys,time
import cv2
import numpy as np
def Imagetonumpy(ImageData):
# 将二进制数据转换为 NumPy 数组
image_array = np.frombuffer(ImageData.buffer, dtype=np.uint8)
# 调整数组形状为 (height, width, channels) # 图是3 通道 就选3 1通道就选1
if (int(len(ImageData.buffer)) == int(ImageData.width*ImageData.height)):
channels=1
else:
channels=3
image_array = image_array.reshape((ImageData.height, ImageData.width,channels))
if channels==3:
image_array = cv2.cvtColor(image_array, cv2.COLOR_RGB2BGR)
return image_array
#*******************************************************************************************
def numpytoImage(numpy_image):
"""
将 NumPy 数组转换为 ImageData 结构体。
参数:
numpy_image: NumPy 数组,形状为 (height, width, channels) 或 (height, width)。
返回:
ImageData: 包含图像数据的结构体。
"""
# 检查 NumPy 数组的形状
if len(numpy_image.shape) == 1: # 灰度图像
height, width,channels = numpy_image.shape
channels = 1
elif len(numpy_image.shape) == 3: # 彩色图像
height, width, channels = numpy_image.shape
else:
raise ValueError("NumPy 数组形状不正确!")
if channels == 3:
numpy_image = cv2.cvtColor(numpy_image, cv2.COLOR_RGB2BGR)
buffer = numpy_image.tobytes()# 将 NumPy 数组转换为二进制数据
# 创建 ImageData 结构体
image_data = ImageData()
image_data.width = width
image_data.height = height
if channels == 3:
image_data.pixel_format = 35127316 # 假设像素格式与原函数一致 35127316
if channels == 1:
image_data.pixel_format = 17301505 # 假设像素格式与原函数一致 35127316
image_data.buffer = buffer
image_data.dataLen = width*height*channels
#image_data.pixel_format 必须正确 否则图像报错 我也不知带这个是啥格式啥结构
# 但是可以通过 输入图像 tmpimg.pixel_format 获取 这个数值
#localVar = IoHelper(data, INIT_LOCAL_VAR)
#tmpimg = moduleVar.img #读取图像
#{tmpimg.width}// 宽度 759
#{tmpimg.height}//高度 658
#{tmpimg.pixel_format}
return image_data
def Process(data) -> int:
"""Write custom logic code inside the Process method. Return 0 for success or any other value for failure."""
"""在Process方法内编写自定义逻辑代码, 成功返回0, 返回其他值表示失败"""
"""Do not delete this code block."""
"""请勿删除此处代码"""
moduleVar = IoHelper(data, INIT_MODULE_VAR)
globalVar = IoHelper(data, INIT_GLOBAL_VAR)
localVar = IoHelper(data, INIT_LOCAL_VAR)
tmpimg = moduleVar.img #读取图像
moduleVar.outstr = fr"""
{tmpimg.width}// 宽度 759
{tmpimg.height}//高度 658
{tmpimg.pixel_format}//像素格式 //35127316
[tmpimg.buffer]//图像数据 二进制
{tmpimg.dataLen}//数据长度 //1498266
{os.getcwd()}
{int(len(tmpimg.buffer))}
{int(tmpimg.width*tmpimg.height)}
{int(len(tmpimg.buffer)) == int(tmpimg.width*tmpimg.height)}
"""
image_array=Imagetonumpy(tmpimg)
#image = cv2.imread(tmpimg)
# 使用 OpenCV 显示图像
#blank_image = np.ones((200, 200, 1), dtype=np.uint8) * 255
#numpy_image = np.zeros((100,100,3),dtype=np.uint8)
#cv2.imshow("Image", image_array)
#cv2.waitKey(2000)
#cv2.destroyAllWindows()
imgooop=numpytoImage(image_array)
moduleVar.imgout=imgooop
"""Variable initialization, to access input and output variables within the Process method."""
"""变量初始化, 进入Process方法后首先调用, 否则无法访问输入、输出变量"""
"""
* Input and output variables:
* 输入、输出变量
Input variables are read-only and cannot be modified; output variables are write-only and cannot be read.
输入变量为只读, 不可以修改; 输出变量为只写, 不可以读取;
Assume: the name of the input variable is 'in0', of type int. Its value can be obtained using tmp = moduleVar.in0
假设: 输入变量名为in0, 类型为int, 可通过tmp = moduleVar.in0 读取该变量的值
Assume: the name of the output variable is 'out0', of type int. Its value can be set using moduleVar.out = 9
假设: 输出变量名为out0, 类型为int, moduleVar.out = 9 设置该变量的值
Global variables:
* 全局变量
Assume: the name of the global variable is 'var0', of type int. Its value can be obtained using tmp = globalVar.GetValue('var0')
假设: 输入变量名为var0, 类型为int, 可通过tmp = globalVar.GetValue('var0') 读取该变量的值, 通过 globalVar.SetValue('var0', 123) 设置该变量的值
Local variables:
* 局部变量
Assume: the name of the local variable is 'var0', of type int. Its value can be obtained using tmp = localVar.GetValue('var0')
假设: 输入变量名为var0, 类型为int, 可通过tmp = localVar.GetValue('var0') 读取该变量的值, 通过 localVar.SetValue('var0', 123) 设置该变量的值
** All variables should be used strictly based on their types. If there is a need for type conversion, explicit conversion should be performed in the user code.
** 所有变量都需要严格根据变量类型使用, 若有类型转换的需求, 应在用户代码内通过显示转换代码进行类型转换。
Example code:
示例代码如下:
width = moduleVar.width + 100
moduleVar.out0 = width / 2 + 20
if moduleVar.in1 == 'OK':
moduleVar.out1 = "OK"
moduleVar.out0 = globalVar.GetValue('var0')
moduleVar.out1 = localVar.GetValue('var0')
globalVar.SetValue('var1', 123)
localVar.SetValue('var1', moduleVar.out2)
Note: Python indentation must be 4 spaces
注意: Python的缩进必须为4个空格。
编写自定义代码,替换下方的默认代码 pass
Write custom code to replace the default code below."
"""
try:
#PrintMsg("\nUser code start")
pass
#PrintMsg("User code end")
except BaseException as e:
PrintMsg(e)
return 0
仔细看 就是2个转换函数: process是被调用方
注意 tmpimg.pixel_format 我没搞懂啥格式.就是一串数字,但是 输入图像是多少,输出就写多少就没有问题.
偶然看文档发现:
file:///C:/Program%20Files/VisionMaster4.4.0/Applications/Help/CH/index.html
浏览 帮助文档 看到了介绍:
帮助文档里面>颜色处理>彩图生成>输出图像像素格式:
int型,代表输出图像的像素格式。其中17301505对应Mono8格式,35127316对应RGB24格式。
那么 意味着 程序 可以没有问题.
美中不足的是VM 用的 python3.7 64位 如果是python3.8 那么python 版本的halcon也可以支持