前面已经说过了,VM4.4 FTP功能不能用,但是VM4.4支持python;python自带FTP不用安装;
VM4.4 自带python没有numpy等第三方库,关于环境配置的前面已经介绍的很详细了.
实在不行可以找配置好的机器替换X64文件夹;
首先搭建FTP服务器:
Quick Easy FTP Server是一个全中文FTP服务器软件,它反应迅速,操作方便,只需要通过简单的几步操作就可以建立自已的ftp服务器,实现了标准FTP服务器所具有的功能。786kb的大小对于一款基于ftp标准协议的ftp服务器软件是非常罕见的。
双击ftpserver.exe
输入账户名:user
输入密码:password
选择根目录:C:\Users\Administrator\Desktop\ftptry [我选择这个位置]
允许下载; 允许上传; 允许改名; 允许删除;允许创建目录 全勾选上
服务>启动服务 或者点击绿色的⚪圈圈; 变红即可.
开机自动运行程序 启动程序自动开启FTP服务 启动后最小化到系统托盘区 全部勾选
users.dat 这是配置 ftptrace.txt 这是日志 删除配置文件可以重新创建;
现在最小化FTP服务器;
打开VM
好了:直接上脚本;
# coding: utf-8
from ioHelper import *
# ioHelper 是VM的东西 必须要
import os,sys,time,io
import cv2
import numpy as np
from ftplib import FTP
import clr
from datetime import datetime
xxx =0
xxx=xxx+10
r"""
int processCount ;
public void Init()
{
}
public bool Process()
{
return true;
}
vmpy脚本 虽然没有 C# 中的 Init函数
但经过实验 发现
Process()前面的所有程序只执行一次 相当于 Init
Process()内部 每次都执行
理由是 xxx 编译第一次执行是11 以后 每次增加 1
当然 你不能在里面写TKinter
也不能指定路径依赖外部的包 除非 你把包 放在 解释器目录
也不能鼠标右击复制粘贴 可以 框选 双击选择 Ctrl+C Ctrl+V Ctrl+X Ctrl+A
"""
def get_ymdhmsm():
r""" 获取 年月日时分 """
now = datetime.now()# 获取当前时间
# 提取年、月、日、时、分、秒、毫秒
year = str(now.year)
month = str(now.month).zfill(2) # 补零,保证两位数
day = str(now.day).zfill(2)
hour = str(now.hour).zfill(2)
minute = str(now.minute).zfill(2)
second = str(now.second).zfill(2)
millisecond = str(now.microsecond // 1000).zfill(4) # 毫秒
folder_path = os.path.join(year, month, day,hour)#年月日时
#作为路径传出
return folder_path
def Imagetonumpy(ImageData):
r""" 海康VMpython 脚本图像 转opencv numpy图像 """
image_array = np.frombuffer(ImageData.buffer, dtype=np.uint8)# 将二进制数据转换为 NumPy 数组
if (int(len(ImageData.buffer)) == int(ImageData.width*ImageData.height)):
channels=1# 调整数组形状为 (height, width, channels) # 图是3 通道 就选3 1通道就选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)# RGB>转BGR
return image_array
#*******************************************************************************************
PIXEL_FORMAT_MONO8 = 17301505
PIXEL_FORMAT_RGB24 = 35127316
# 通过查阅手册 模块介绍>颜色处理>颜色转换: 明确说明
#输出图像像素格式
#int型,代表输出图像的像素格式。其中17301505对应Mono8格式,35127316对应RGB24格式。
# VisionMaster4.4 python脚本 不支持 Tab 只能用4个空格 否则编辑器不能识别;
def numpytoImage(numpy_image):
"""
将 NumPy 数组转换为 海康VM py 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 数组转换为二进制数据
image_data = ImageData()# 创建 ImageData 结构体
image_data.width = width
image_data.height = height
if channels == 3:
image_data.pixel_format = PIXEL_FORMAT_RGB24 #
if channels == 1:
image_data.pixel_format = PIXEL_FORMAT_MONO8 #
image_data.buffer = buffer
image_data.dataLen = width*height*channels
return image_data
def upload_file_to_ftp(ftp_server, username, password, local_file_path, remote_file_path):
"""
上传本地文件 到 FTP 根目录
:param ftp_server: FTP:IP
:param username: 用户名
:param password: 密码
:param local_file_path: 本地文件路径
:param remote_file_path: 远程文件路径
"""
try:
ftp = FTP(ftp_server)# 创建FTP连接
ftp.login(username, password)
with open(local_file_path, 'rb') as file:
ftp.storbinary(f'STOR {remote_file_path}', file)
except Exception as e:
pass
finally:
if 'ftp' in locals():
ftp.quit()
def upload_image_to_ftp(ftp_server, username, password, image, remote_file_path):
"""
上传 图型变量 [numpy格式] 到 FTP 根目录
:param ftp_server: FTP服务器地址
:param username: 用户名
:param password: 密码
:param image: OpenCV图像变量
:param remote_file_path: 远程文件路径
"""
try:
# 将OpenCV图像转换为字节流
kkkk, img_encoded = cv2.imencode('.png', image) # 将图像编码为png格式
img_bytes = io.BytesIO(img_encoded) # 将编码后的图像数据转换为字节流
ftp = FTP(ftp_server)
ftp.login(username, password)
ftp.storbinary(f'STOR {remote_file_path}', img_bytes)
except Exception as e:
print(f"Error: {e}")
finally:
if 'ftp' in locals():
ftp.quit()
def upload_mkd_image_to_ftp(ftp_server, username, password, image, remote_folder, remote_file_name):
"""
创建文件夹 并上传 图型变量 [numpy格式] 到 创建目录
:param ftp_server: FTP服务器地址
:param username: 用户名
:param password: 密码
:param image: OpenCV图像变量
:param remote_folder: 远程文件夹名称(在FTP根目录下创建)可以是 多个文件夹
:param remote_file_name: 远程文件名
"""
try:
# 将OpenCV图像转换为字节流
_, img_encoded = cv2.imencode('.png', image) # 将图像编码为JPEG格式
img_bytes = io.BytesIO(img_encoded) # 将编码后的图像数据转换为字节流
# 创建FTP连接
ftp = FTP(ftp_server)
ftp.login(username, password)
# 创建远程文件夹(如果不存在)
try:
ftp.mkd(remote_folder) # 创建文件夹
except Exception as e:
pass
# 切换到目标文件夹
ftp.cwd(remote_folder)
# 构造远程文件路径
remote_file_path = f"{remote_folder}/{remote_file_name}"
# 上传字节流到FTP服务器
ftp.storbinary(f'STOR {remote_file_name}', img_bytes)
except Exception as e:
pass
finally:
if 'ftp' in locals():
ftp.quit()
def Process(data) -> int:
"""在Process方法内编写自定义逻辑代码, 成功返回0, 返回其他值表示失败"""
global xxx
xxx=xxx+1
moduleVar = IoHelper(data, INIT_MODULE_VAR)#模块输入输出变量...
globalVar = IoHelper(data, INIT_GLOBAL_VAR)#全局变量...
localVar = IoHelper(data, INIT_LOCAL_VAR) #局部变量...
r"""
输入变量:
img (IMAGE)0 图像源1.图像[]
"""
r"""
输出变量:
imgout(IMAGE)
outstr(string)
out0(string)
"""
tmpimg = moduleVar.img #读取图像
moduleVar.outstr = fr"""
{tmpimg.width}// 宽度 759
{tmpimg.height}//高度 658
"""
image_array=Imagetonumpy(tmpimg)# 转成 opencv numpy格式
#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) # numpy转海康图像
moduleVar.imgout=imgooop#图像输出到模块输出
Plk=os.getcwd()
ftp_server = "127.0.0.1"
username = "user"
password = "password"
local_file_path = fr"C:\Users\Administrator\Desktop\ftptry\0.bmp"
SaveFileName=time.strftime('%Y-%m-%d_%H_%M_%S')
remote_file_path = fr"/{SaveFileName}_ftp.png"
moduleVar.out0=local_file_path+"\n "+SaveFileName+"\n"+remote_file_path
remote_folder = fr"my_images/{get_ymdhmsm()}" # 在FTP根目录下创建的文件夹
#文件夹 \my_images\2025\02\28\16
#文件名 2025-02-28_16_15_52ftp.png
#假设 FPT根目录是 C:\Users\Administrator\Desktop\ftptry
#那么就会多级目录的文件夹 C:\Users\Administrator\Desktop\ftptry\my_images\2025\02\28\16
#upload_file_to_ftp(ftp_server, username, password, local_file_path, remote_file_path)
#upload_image_to_ftp(ftp_server, username, password, image_array, remote_file_path)
remote_file_name = time.strftime('%Y-%m-%d_%H_%M_%S')+"ftp.png"
upload_mkd_image_to_ftp(ftp_server, username, password, image_array, remote_folder, remote_file_name)
"""
变量初始化, 进入Process方法后首先调用, 否则无法访问输入、输出变量
输入变量为只读, 不可以修改; 输出变量为只写, 不可以读取;
所有变量都需要严格根据变量类型使用, 若有类型转换的需求, 应在用户代码内通过显示转换代码进行类型转换。
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)
注意: Python的缩进必须为4个空格。
"""
try:
#PrintMsg("\nUser code start")
pass
PrintMsg("User code end")
except BaseException as e:
PrintMsg(e)
return 0
759*658的彩色图用了37.51ms
如果频率不高一秒钟一张图还是够的.