• 以下代码运行可外接设备串口摄像头COM5的一个静止图像,如何修改才能实现获取图像数据的刷新,让运行弹出窗口的图像有实时显示功能


    关注 码龄 粉丝数 原力等级 -- 被采纳 被点赞 采纳率 donotlikepython 2024-04-09 18:51 采纳率: 33.3% 浏览 6 首页/ 编程语言 / 以下代码运行可外接设备串口摄像头COM5的一个静止图像,如何修改才能实现获取图像数据的刷新,让运行弹出窗口的图像有实时显示功能 python 以下代码运行可外接设备串口摄像头COM5的一个静止图像,如何修改才能实现获取图像数据的刷新,让运行弹出窗口的图像有实时显示功能 #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import sys import copy import time import math from functools import partial import serial import struct import socket import datetime import numpy as np import pyvisa as visa import matplotlib.pyplot as plt from PIL import ImageTk from mpl_toolkits.axes_grid1.inset_locator import zoomed_inset_axes from mpl_toolkits.axes_grid1.inset_locator import mark_inset from pygame._sdl2 import Image plt.rcParams['font.family'] = "Times New Roman" #========================================================================================# ## plot parameters lw_grid = 0.5 # grid linewidth(栅格线宽) fig_dpi = 800 # save figure's resolution(保存图形的分辨率) #=========================================================================== freqency = 1000 duration = 1000 ''' @author: Wei Zhang @date: 2021-03-29 This script is used to receive UART data from Camera (Model: OV7670). ''' #========================================================================================# def main(): read_bytes = [] Start_Frame = 5 try: ser = serial.Serial('COM5', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) except: ser = serial.Serial('/dev/tty.usbmodem144101', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE) print("Serial port: %s"%ser.name) i = 0 while(True): if ser.in_waiting: if i < Start_Frame: if ser.readline(ser.in_waiting) == b'*RDY*': # find the first "*RDY*"(找到第一个“*RDY*”) i += 1 if i == Start_Frame: print("Start receiving camera data...") elif i == Start_Frame: # receive one frame camera data(接收单帧摄像机数据) byte_str = ser.readline(ser.in_waiting) if (byte_str == b'*RDY*'): i += 1 else: # print(byte_str) read_bytes += list(byte_str) # store one frame camera data(存储单帧相机数据) else: # break(终止) break print(len(read_bytes)) import tkinter as tk import numpy as np from PIL import Image def display_image_in_tkinter(read_bytes): if read_bytes: # Reshape data to image dimensions x = np.reshape(read_bytes, (240, 320)) # Create Tkinter window root = tk.Tk() root.title("Image Viewer") # Create canvas to display image canvas = tk.Canvas(root, width=320, height=240) canvas.pack() # Convert numpy array to Tkinter-compatible format img = np.uint8(x) img = Image.fromarray(img) # Convert to PhotoImage img_tk = ImageTk.PhotoImage(image=img) # Display image on canvas canvas.create_image(0, 0, anchor=tk.NW, image=img_tk) # Run Tkinter main loop root.mainloop() display_image_in_tkinter(read_bytes) #========================================================================================# if __name__ == "__main__": main() 展开全部 收起 写回答 好问题 0 提建议 追加酬金 关注问题 微信扫一扫 点击复制链接 分享 邀请回答 编辑 收藏 删除 结题 收藏 举报 追加酬金 (90%的用户在追加酬金后获得了解决方案) 当前问题酬金 ¥ 0 (可追加 ¥500) ¥ 15¥ 20¥ 50¥ 100¥ 200 支付方式 扫码支付 二维码出错 点击刷新 支付金额 15 元 提供问题酬金的用户不参与问题酬金结算和分配 支付即为同意 《付费问题酬金结算规则》 结题 再想想 删除 再等等

    3条回答 默认 最新

    • 阿里嘎多学长 2024-04-09 18:51
      关注

      以下内容由CHATGPT及阿里嘎多学长共同生成、有用望采纳:


      要实现实时显示串口摄像头图像,你需要在主循环中不断读取新的数据并更新显示。这里是一个简单的修改版本,它会在每次收到新数据时调用display_image_in_tkinter函数来更新图像:

      import threading
      
      # ... 其他代码保持不变 ...
      
      def update_image(read_bytes):
          while True:
              if ser.in_waiting:
                  if i < Start_Frame:
                      if ser.readline(ser.in_waiting) == b'*RDY*':
                          i += 1
                          if i == Start_Frame:
                              print("Start receiving camera data...")
                  elif i == Start_Frame:
                      byte_str = ser.readline(ser.in_waiting)
                      if (byte_str == b'*RDY*'):
                          i += 1
                      else:
                          read_bytes += list(byte_str)
                          # 更新图像
                          display_image_in_tkinter(read_bytes)
              # 添加一个定时器来控制读取频率,例如每秒读取一次
              time.sleep(1 / freqency)  # 修改为需要的刷新频率
      
      def display_image_in_tkinter(read_bytes):
          # ... 原来的 display_image_in_tkinter 函数内容 ...
      
      # 在主函数中启动一个新的线程来处理图像更新
      read_bytes_thread = threading.Thread(target=update_image, args=(read_bytes,))
      read_bytes_thread.start()
      
      # ... 然后保留原来的 main 函数的其他部分 ...
      

      这个修改后的代码会在后台线程中持续读取数据,并在主线程中通过display_image_in_tkinter函数更新图像。这样,你就可以看到实时的图像了。记得根据你的需求调整time.sleep(1 / freqency)行中的刷新频率。

      展开全部

      评论 编辑记录
    • GISer Liu 2024-04-09 20:01
      关注

      该回答引用自GPT-3.5,由博主GISer Liu编写:

      根据你的描述,你想要修改代码,实现从串口摄像头获取实时图像数据,并在 Tkinter 窗口中实时显示。以下是解决问题的思路和方案:

      思路:

      1. 实时获取图像数据 :修改代码,使其能够持续从串口接收图像数据,而不仅仅是获取一帧数据。
      2. 定时刷新显示 :使用 Tkinter 的定时器或者多线程机制,定时刷新图像显示,以实现实时显示效果。

        解决方案:

        1. 实时获取图像数据:

        要实现持续从串口接收图像数据,可以修改 main()
        函数中的循环部分,使其能够不断接收数据并存储。不需要设置一个固定的帧数,而是在收到新数据时立即更新显示。
        pythonCopy code
        def main():
        read_bytes = []
        try:
        ser = serial.Serial('COM5', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
        except:
        ser = serial.Serial('/dev/tty.usbmodem144101', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
        print("Serial port: %s" % ser.name)
        def receive_data():
        nonlocal read_bytes
        while True:
        if ser.in_waiting:
        byte_str = ser.readline(ser.in_waiting)
        if byte_str == b'*RDY*':
        continue
        read_bytes += list(byte_str)
        # 启动接收数据的线程
        import threading
        data_thread = threading.Thread(target=receive_data)
        data_thread.start()
        # 在主线程中实时显示图像
        display_image_in_tkinter(read_bytes)
        

        2. 定时刷新显示:

        使用 Tkinter 的 after() 方法,或者结合 threading
        模块创建一个定时器,定时调用显示图像的函数,以实现定时刷新。
        pythonCopy code
        def main():
        read_bytes = []
        try:
        ser = serial.Serial('COM5', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
        except:
        ser = serial.Serial('/dev/tty.usbmodem144101', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
        print("Serial port: %s" % ser.name)
        def receive_data():
        nonlocal read_bytes
        while True:
        if ser.in_waiting:
        byte_str = ser.readline(ser.in_waiting)
        if byte_str == b'*RDY*':
        continue
        read_bytes += list(byte_str)
        # 启动接收数据的线程
        import threading
        data_thread = threading.Thread(target=receive_data)
        data_thread.start()
        # 在主线程中定时刷新显示图像
        import tkinter as tk
        def display_and_refresh():
        display_image_in_tkinter(read_bytes)
        root.after(1000, display_and_refresh)  # 每隔一秒刷新显示
        root = tk.Tk()
        root.title("Real-time Image Viewer")
        display_and_refresh()
        root.mainloop()
        

        注意事项:

      • 需要确保串口摄像头能够持续发送图像数据,以及图像数据的格式与解析是否正确。
      • 在多线程中操作共享数据时,需要注意线程安全问题,可以使用锁机制进行保护。
        以上就是针对你的问题的解决方案,如果有任何疑问,欢迎提出。

      如果该回答解决了您的问题,请采纳!如果没有,请私信联系或评论您的疑惑

      展开全部

      评论
    • Kwan的解忧杂货铺 Java领域优质创作者 2024-04-15 23:39
      关注

      晚上好🌙🌙🌙
      本答案参考ChatGPT-3.5

      问题:如何在Python中修改代码以获取图像数据的刷新,以实现弹出窗口的实时图像显示?

      解决方案:

      1. 导入必要的模块: numpymatploylibPILTkinterImageTkserial
      2. 在主函数中添加一个while循环以实现实时图像显示。对于每个循环,使用缓冲区中的readline()函数读取串口数据,将其存储在缓冲区中。
      3. 将读取的数据转换为像素颜色,并将其转换为PIL Image对象。
      4. 将PIL Image对象转换为Tkinter-compatible格式,并将其显示在canvas上。
      5. 在Tkinter主循环中添加update_idletasks()after()函数,以对canvas进行更新,并指定图像刷新间隔时间。

      以下是修改后的代码:

      #!/usr/bin/env python3
      # -*- coding: utf-8 -*-
      import os
      import sys
      import copy
      import time
      import math
      from functools import partial
      import serial
      import struct
      import socket
      import datetime
      import numpy as np
      import matplotlib.pyplot as plt
      from PIL import Image, ImageTk
      import tkinter as tk
      
      
      plt.rcParams['font.family'] = "Times New Roman"
      #===========================================================================
      freqency = 1000
      duration = 1000
      
      
      def main():
          read_bytes = []
          Start_Frame = 5
          try:
              ser = serial.Serial('COM5', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
          except:
              ser = serial.Serial('/dev/tty.usbmodem144101', baudrate=1000000, bytesize=serial.EIGHTBITS, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE)
          print("Serial port: %s" % ser.name)
          i = 0
          root = tk.Tk()
          root.title("Image Viewer")
          canvas = tk.Canvas(root, width=320, height=240)
          canvas.pack()
          while True:
              # Read data from serial port
              if ser.in_waiting:
                  if i < Start_Frame:
                      if ser.readline(ser.in_waiting) == b'*RDY*':
                          i += 1
                          if i == Start_Frame:
                              print("Start receiving camera data...")
                  elif i == Start_Frame:
                      byte_str = ser.readline(ser.in_waiting)
                      if (byte_str == b'*RDY*'):
                          i += 1
                      else:
                          read_bytes += list(byte_str)
                  else:
                      break
      
              # Convert raw data to image
              if len(read_bytes) == 307200:
                  pixel_data = np.array(read_bytes).reshape((240, 320))
                  img = Image.fromarray(pixel_data).convert(mode="RGB")
                  tk_img = ImageTk.PhotoImage(img)
                  canvas.create_image(0, 0, image=tk_img, anchor="nw")
                  root.update_idletasks()
                  root.after(1)
      
          ser.close()
      
      
      if __name__ == "__main__":
          main()
      
      

      修改说明:

      1. 将Tkinter窗口和canvas的创建移至函数外部。
      2. 添加了一个无限循环,读取和转换图像数据,并在canvas中显示图像
      3. 在Tkinter主循环中添加了update_idletasks()after()函数,以进行canvas更新和指定图像刷新时间。

      展开全部

      评论
    编辑
    预览

    报告相同问题?

  • 相关阅读:
    redis分布式秒杀锁
    十五、Java中I/O流
    Linux系统零基础入门之基本操作
    vivado SLR
    【matlab】随机森林客户流失预测
    妙啊,Python 管道 Pipe 编写代码如此优雅
    C语言学习系列-->字符函数和字符串函数
    Vue--组件数据传递与组件切换
    clion出现createprocess error=193, %1 不是有效的 win32 应用程序
    malloc是如何实现内存分配的?
  • 原文地址:https://ask.csdn.net/questions/8085847