【问题标题】:Run same script in different threads python在不同的线程python中运行相同的脚本
【发布时间】:2020-08-23 14:57:00
【问题描述】:

我有一个脚本可以识别来自相机的板块,现在我需要相同的脚本来识别其他相机,所以简而言之,它需要同时识别两个相机,我正在使用 Tensoflow/keras 和 YOLO 对象检测,可以有人建议解决这个问题,我尝试了不同的线程,但我无法启动第二个线程,我将发布我尝试过的内容

import sys, os
import threading
import keras
import cv2
import traceback
import numpy as np
import time
import sqlite3
import pyodbc
import time
from imutils.video import  VideoStream
from pattern import apply_pattern
import darknet.python.darknet as dn
from os.path import splitext, basename
from glob import glob
from darknet.python.darknet import detect
from src.label import dknet_label_conversion
from src.utils import nms
from src.keras_utils import load_model
from glob import glob
from os.path import splitext, basename
from src.utils import im2single
from src.keras_utils import load_model, detect_lp
from src.label import Shape, writeShapes
import imutils
cam_vlez ="rtsp://"
cam_izlez = "rtsp://a"


def adjust_pts(pts,lroi):
     return pts*lroi.wh().reshape((2,1)) + lroi.tl().reshape((2,1))


def start_vlez(cam):
    while True:
        cap = VideoStream(cam).start()
        start_time = time.time()
        sky = cap.read()
        frame = sky[100:700, 300:1800]

        w = frame.shape[0]
        h = frame.shape[1]
        ratio = float(max(frame.shape[:2])) / min(frame.shape[:2])
        side = int(ratio * 288.)
        bound_dim = min(side + (side % (2 ** 4)), 608)

        Llp,LlpImgs,_ = detect_lp(wpod_net,im2single(frame),bound_dim,2**4,(240,80),lp_threshold)
        cv2.imshow('detected_plate', frame)
        if len(LlpImgs):
            Ilp = LlpImgs[0]
            s = Shape(Llp[0].pts)
            for shape in [s]:
                ptsarray = shape.pts.flatten()
                try:
                    frame = cv2.rectangle(frame,(int(ptsarray[0]*h), int(ptsarray[5]*w)),(int(ptsarray[1]*h),int(ptsarray[6]*w)),(0,255,0),3)
                    cv2.imshow('detected_plate', frame)
                except:
                    traceback.print_exc()
                    sys.exit(1)
            Ilp = cv2.cvtColor(Ilp, cv2.COLOR_BGR2GRAY)

            Ilp = cv2.cvtColor(Ilp, cv2.COLOR_GRAY2BGR)
            cv2.imwrite('%s/_lp.png' % (output_dir),Ilp*255.)
            cv2.imshow('lp_bic', Ilp)
            R,(width,height) = detect(ocr_net, ocr_meta, 'lp_images/_lp.png' ,thresh=ocr_threshold, nms=None)
            if len(R):


                L = dknet_label_conversion(R,width,height)
                L = nms(L,.45)

                L.sort(key=lambda x: x.tl()[0])
                lp_str = ''.join([chr(l.cl()) for l in L])


                result =apply_pattern(lp_str)
                write_to_database(result)




                print("License Plate Detected: ", lp_str)
                print("Written in database: ", result)


                print("--- %s seconds ---" % (time.time() - start_time))
                #updateSqliteTable(lp_str)


def start_izlez(cam):
    while True:
        cap = VideoStream(cam).start()
        start_time = time.time()
        sky = cap.read()
        frame = sky[100:700, 300:1800]

        w = frame.shape[0]
        h = frame.shape[1]
        ratio = float(max(frame.shape[:2])) / min(frame.shape[:2])
        side = int(ratio * 288.)
        bound_dim = min(side + (side % (2 ** 4)), 608)

        Llp,LlpImgs,_ = detect_lp(wpod_net,im2single(frame),bound_dim,2**4,(240,80),lp_threshold)
        cv2.imshow('detected_plate1', frame)
        if len(LlpImgs):
            Ilp = LlpImgs[0]
            s = Shape(Llp[0].pts)
            for shape in [s]:
                ptsarray = shape.pts.flatten()
                try:
                    frame = cv2.rectangle(frame,(int(ptsarray[0]*h), int(ptsarray[5]*w)),(int(ptsarray[1]*h),int(ptsarray[6]*w)),(0,255,0),3)
                    cv2.imshow('detected_plate1', frame)
                except:
                    traceback.print_exc()
                    sys.exit(1)
            Ilp = cv2.cvtColor(Ilp, cv2.COLOR_BGR2GRAY)

            Ilp = cv2.cvtColor(Ilp, cv2.COLOR_GRAY2BGR)
            cv2.imwrite('%s/_lp.png' % (output_dir),Ilp*255.)
            cv2.imshow('lp_bic', Ilp)
            R,(width,height) = detect(ocr_net, ocr_meta, 'lp_images/_lp.png'            ,thresh=ocr_threshold, nms=None)
            if len(R):


                L = dknet_label_conversion(R,width,height)
                L = nms(L,.45)

                L.sort(key=lambda x: x.tl()[0])
                lp_str = ''.join([chr(l.cl()) for l in L])

                result =apply_pattern(lp_str)
                write_to_database(result)

                print("License Plate Detected: ", lp_str)
                print("Written in database: ", result)

                print("--- %s seconds ---" % (time.time() - start_time))
                #updateSqliteTable(lp_str)


if __name__ == '__main__':
    try:
        output_dir = 'lp_images/'

        lp_threshold = .5
        wpod_net_path = "./my-trained-model/my-trained-model1_final.json"
        wpod_net = load_model(wpod_net_path)
        ocr_threshold = .6
        ocr_weights = b'data/ocr/ocr-net.weights'
        ocr_netcfg = b'data/ocr/ocr-net.cfg'
        ocr_dataset = b'data/ocr/ocr-net.data'
        ocr_net = dn.load_net(ocr_netcfg, ocr_weights, 0)
        ocr_meta = dn.load_meta(ocr_dataset)

        t = threading.Thread(target=start_vlez(cam_izlez))
        t1 = threading.Thread(target=start_izlez(cam_vlez))

        t.start()
        t1.start()
    except:
     print ("Error: unable to start thread")

【问题讨论】:

  • 当您尝试运行此代码时遇到什么错误?
  • 我只是无法启动线程
  • 你应该只创建一次VideoStream(cam) - 在while True之前
  • Thread 需要不带 () 和参数的函数名称 - 稍后它将使用 () 启动它。如果你有争论,那么你需要(target=start_vlez, args=(cam_izlez,))。在您当前的代码中,您在当前线程中启动函数,因此它必须等待结束才能运行另一个函数。

标签: python tensorflow keras yolo


【解决方案1】:

Thread 中的target= 需要不带 () 和参数的函数名称 - 稍后它将使用 () 来启动它。

您当前的代码不会在线程中运行函数,但它的工作方式类似于

result = start_vlez(cam_izlez)
result1 = start_izlez(cam_vlez)

t = threading.Thread(target=result)
t1 = threading.Thread(target=result1)

t.start()
t2.start()

所以它在主线程中运行第一个函数并等待它结束。接下来它也在主线程中运行第二个函数并等待它结束。之后它会尝试使用Thread

如果您有参数,那么您需要在target= 中使用不带() 的函数名称,并在args= 中使用带参数的元组

t = threading.Thread(target=start_vlez, args=(cam_izlez,))

t1 = threading.Thread(target=start_izlez, args=(cam_vlez,))

args= 即使对于单个参数也需要元组,所以我在 (cam_izlez,)(cam_vlez,) 中使用 ,

【讨论】:

  • 哇,谢谢,它确实有效,我设法在线程中调用了这两个函数,非常感谢你,但现在我收到一个错误文件“/home/anpr/anaconda3/envs /tf/lib/python3.7/site-packages/keras/backend/tensorflow_backend.py", line 73, in symbolic_fn_wrapper if _SYMBOLIC_SCOPE.value: AttributeError: '_thread._local' object has no attribute 'value'
  • 你认为是因为他们使用的是相同的模型吗?
  • 我不知道 - 创建新问题并输入完整的错误消息(从单词 Traceback 开始)。我将首先检查它仅适用于第一个线程,然后我将检查它如何仅适用于第二个线程。也许你有一些与两个线程无关的错误。如果两者都能正常工作,那么您可以尝试加载模型两次。很简单:先试后问。
  • 好的,非常感谢您的帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 2015-11-17
  • 2019-07-09
  • 1970-01-01
  • 2012-04-05
相关资源
最近更新 更多