构建 Python 相机 SDK 并使用它进行多条码扫描

wufei123 2025-01-26 阅读:9 评论:0
现在,轻量级 c 相机 sdk 已针对 windows、linux 和 macos 完成,我们可以将其集成到其他高级编程语言中。在本文中,我们将探讨如何基于 c 相机库构建 python 相机 sdk,并使用它与 dynamsoft...

现在,轻量级 c 相机 sdk 已针对 windows、linux 和 macos 完成,我们可以将其集成到其他高级编程语言中。在本文中,我们将探讨如何基于 c 相机库构建 python 相机 sdk,并使用它与 dynamsoft barcode reader sdk 进行多条码扫描。

python 多条码扫描仪演示视频 搭建 cpython 扩展项目的脚手架

cpython 扩展是一个共享库(例如,windows 上的 dll、linux 上的 .so 或 macos 上的 .dylib)可以在运行时加载到python解释器中并用于扩展其功能。 lite相机cpython扩展项目的结构如下:

python-lite-camera
│
│── include
│   ├── camera.h
│   ├── camerapreview.h
│   ├── stb_image_write.h
│── lib
│   ├── linux
│   │   ├── liblitecam.so
│   ├── macos
│   │   ├── liblitecam.dylib
│   ├── windows
│   │   ├── litecam.dll
│   │   ├── litecam.lib
├── src
│   ├── litecam.cpp
│   ├── pycamera.h
│   ├── pywindow.h
│── litecam
│   ├── __init__.py
│── setup.py
│── manifest.in
│── readme.md

说明:

  • include:c 相机库的头文件。
  • lib:c 相机库的共享库。
  • src:python相机sdk的源代码。
  • litecam:python 扩展的入口点。
  • setup.py:构建脚本。
  • manifest.in:包含非python文件的清单文件。
  • readme.md:文档。
为 python 扩展编写构建脚本 setup.py

在setup.py中添加以下内容:

from setuptools.command import build_ext
from setuptools import setup, extension
import sys
import os
import io
from setuptools.command.install import install
import shutil
from pathlib import path

lib_dir = ''

sources = [
    "src/litecam.cpp",
]

include_dirs = [os.path.join(os.path.dirname(__file__), "include")]

libraries = ['litecam']

extra_compile_args = []

if sys.platform == "linux" or sys.platform == "linux2":
    lib_dir = 'lib/linux'
    extra_compile_args = ['-std=c++11']
    extra_link_args = ["-wl,-rpath=$origin"]
elif sys.platform == "darwin":
    lib_dir = 'lib/macos'
    extra_compile_args = ['-std=c++11']
    extra_link_args = ["-wl,-rpath,@loader_path"]
elif sys.platform == "win32":
    lib_dir = 'lib/windows'
    extra_link_args = []

else:
    raise runtimeerror("unsupported platform")


long_description = io.open("readme.md", encoding="utf-8").read()

module_litecam = extension(
    "litecam",
    sources=sources,
    include_dirs=include_dirs,
    library_dirs=[lib_dir],
    libraries=libraries,
    extra_compile_args=extra_compile_args,
    extra_link_args=extra_link_args,
)

def copyfiles(src, dst):
    if os.path.isdir(src):
        filelist = os.listdir(src)
        for file in filelist:
            libpath = os.path.join(src, file)
            shutil.copy2(libpath, dst)
    else:
        shutil.copy2(src, dst)


class custombuildext(build_ext.build_ext):
    def run(self):
        build_ext.build_ext.run(self)
        dst = os.path.join(self.build_lib, "litecam")
        copyfiles(lib_dir, dst)
        filelist = os.listdir(self.build_lib)
        for file in filelist:
            filepath = os.path.join(self.build_lib, file)
            if not os.path.isdir(file):
                copyfiles(filepath, dst)
                os.remove(filepath)


class custombuildextdev(build_ext.build_ext):
    def run(self):
        build_ext.build_ext.run(self)
        dev_folder = os.path.join(path(__file__).parent, 'litecam')
        copyfiles(lib_dir, dev_folder)
        filelist = os.listdir(self.build_lib)
        for file in filelist:
            filepath = os.path.join(self.build_lib, file)
            if not os.path.isdir(file):
                copyfiles(filepath, dev_folder)


class custominstall(install):
    def run(self):
        install.run(self)


setup(name='lite-camera',
      version='2.0.1',
      description='litecam is a lightweight, cross-platform library for capturing rgb frames from cameras and displaying them. designed with simplicity and ease of integration in mind, litecam supports windows, linux and macos platforms.',
      long_description=long_description,
      long_description_content_type="text/markdown",
      author='yushulx',
      url='https://github.com/yushulx/python-lite-camera',
      license='mit',
      packages=['litecam'],
      ext_modules=[module_litecam],
      classifiers=[
           "development status :: 5 - production/stable",
           "environment :: console",
           "intended audience :: developers",
          "intended audience :: education",
          "intended audience :: information technology",
          "intended audience :: science/research",
          "license :: osi approved :: mit license",
          "operating system :: microsoft :: windows",
          "operating system :: macos",
          "operating system :: posix :: linux",
          "programming language :: python",
          "programming language :: python :: 3",
          "programming language :: python :: 3 :: only",
          "programming language :: python :: 3.6",
          "programming language :: python :: 3.7",
          "programming language :: python :: 3.8",
          "programming language :: python :: 3.9",
          "programming language :: python :: 3.10",
          "programming language :: python :: 3.11",
          "programming language :: python :: 3.12",
          "programming language :: c++",
          "programming language :: python :: implementation :: cpython",
          "topic :: scientific/engineering",
          "topic :: software development",
      ],
      cmdclass={
          'install': custominstall,
          'build_ext': custombuildext,
          'develop': custombuildextdev},
      )

说明:

  • lite-camera:python 包的名称。
  • ext_modules:cpython 扩展列表。它指定不同平台的源文件、包含目录、库目录、库以及编译/链接标志。
  • 开发:用于开发的自定义命令。它将共享库复制到 litecam 文件夹以方便测试。
  • build_ext:自定义构建过程,将共享库打包到wheel包中。
用 c 实现 python camera sdk api

pycamera.h 文件定义了用于从相机捕获帧的 pycamera python 类,而 pywindow.h 文件定义了用于在窗口中显示帧的 pywindow python 类。 litecam.cpp 文件作为 python 扩展的入口点,其中定义了一些全局方法,并注册了 pycamera 和 pywindow 类。

pycamera.h 包括
#include <python.h>
#include <structmember.h>
#include "camera.h"
  • python.h:包含使用 python c api。
  • structmember.h:提供用于管理对象成员的宏和帮助器。
  • camera.h:定义 camera 类,pycamera 扩展对其进行包装。
pycamera 结构体定义
typedef struct
{
    pyobject_head camera *handler;
} pycamera;

pycamera 结构体表示包装 c camera 对象的 python 对象。该处理程序是一个指向 camera 类实例的指针。

方法
  • pycamera_dealloc

    8556677774455

    解除分配 camera 对象并释放关联的内存。

  • pycamera_new

    static pyobject *pycamera_new(pytypeobject *type, pyobject *args, pyobject *kwds)
    {
        pycamera *self;
    
        self = (pycamera *)type-&gt;tp_alloc(type, 0);
        if (self != null)
        {
            self-&gt;handler = new camera();
        }
    
        return (pyobject *)self;
    }
    
    

    创建 pycamera 的新实例。它为python对象分配内存,创建一个新的camera对象,并将其分配给self->handler。

  • 开放

    static pyobject *open(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        int index = 0;
        if (!pyarg_parsetuple(args, "i", &amp;index))
        {
            return null;
        }
    
        bool ret = self-&gt;handler-&gt;open(index);
        return py_buildvalue("i", ret);
    }
    

    打开指定索引的相机。

  • 列表媒体类型

    static pyobject *listmediatypes(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        std::vector<mediatypeinfo> mediatypes = self-&gt;handler-&gt;listsupportedmediatypes();
    
        pyobject *pylist = pylist_new(0);
    
        for (size_t i = 0; i 
    
    
    <p>返回支持的媒体类型列表。对于 windows,它将宽字符串转换为 python unicode 对象。</p>
    </mediatypeinfo>
  • 发布

    static pyobject *release(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        self-&gt;handler-&gt;release();
        py_return_none;
    }
    

    释放相机。

  • 设置分辨率

    static pyobject *setresolution(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
        int width = 0, height = 0;
        if (!pyarg_parsetuple(args, "ii", &amp;width, &amp;height))
        {
            return null;
        }
        int ret = self-&gt;handler-&gt;setresolution(width, height);
        return py_buildvalue("i", ret);
    }
    

    设置相机的分辨率。

  • 捕获帧

    static pyobject *captureframe(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        framedata frame = self-&gt;handler-&gt;captureframe();
        if (frame.rgbdata)
        {
            pyobject *rgbdata = pybytearray_fromstringandsize((const char *)frame.rgbdata, frame.size);
            pyobject *pyframe = py_buildvalue("iiio", frame.width, frame.height, frame.size, rgbdata);
            releaseframe(frame);
    
            return pyframe;
        }
        else
        {
            py_return_none;
        }
    }
    

    从相机捕获帧并将 rgb 数据作为 python 字节数组返回。

  • getwidth 和 getheight

    static pyobject *getwidth(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        int width = self-&gt;handler-&gt;framewidth;
        return py_buildvalue("i", width);
    }
    
    static pyobject *getheight(pyobject *obj, pyobject *args)
    {
        pycamera *self = (pycamera *)obj;
    
        int height = self-&gt;handler-&gt;frameheight;
        return py_buildvalue("i", height);
    }
    

    返回捕获帧的宽度和高度。

实例方法
static pymethoddef instance_methods[] = {
    {"open", open, meth_varargs, null},
    {"listmediatypes", listmediatypes, meth_varargs, null},
    {"release", release, meth_varargs, null},
    {"setresolution", setresolution, meth_varargs, null},
    {"captureframe", captureframe, meth_varargs, null},
    {"getwidth", getwidth, meth_varargs, null},
    {"getheight", getheight, meth_varargs, null},
    {null, null, 0, null}};

定义 pycamera python 对象上可用的方法。这些方法与上面定义的相应 c 函数相关联。

pycamera类型
static pytypeobject pycameratype = {
    pyvarobject_head_init(null, 0) "litecam.pycamera", /* tp_name */
    sizeof(pycamera),                                  /* tp_basicsize */
    0,                                                 /* tp_itemsize */
    (destructor)pycamera_dealloc,                      /* tp_dealloc */
    0,                                                 /* tp_print */
    0,                                                 /* tp_getattr */
    0,                                                 /* tp_setattr */
    0,                                                 /* tp_reserved */
    0,                                                 /* tp_repr */
    0,                                                 /* tp_as_number */
    0,                                                 /* tp_as_sequence */
    0,                                                 /* tp_as_mapping */
    0,                                                 /* tp_hash  */
    0,                                                 /* tp_call */
    0,                                                 /* tp_str */
    pyobject_genericgetattr,                           /* tp_getattro */
    pyobject_genericsetattr,                           /* tp_setattro */
    0,                                                 /* tp_as_buffer */
    py_tpflags_default | py_tpflags_basetype,          /*tp_flags*/
    "pycamera",                                        /* tp_doc */
    0,                                                 /* tp_traverse */
    0,                                                 /* tp_clear */
    0,                                                 /* tp_richcompare */
    0,                                                 /* tp_weaklistoffset */
    0,                                                 /* tp_iter */
    0,                                                 /* tp_iternext */
    instance_methods,                                  /* tp_methods */
    0,                                                 /* tp_members */
    0,                                                 /* tp_getset */
    0,                                                 /* tp_base */
    0,                                                 /* tp_dict */
    0,                                                 /* tp_descr_get */
    0,                                                 /* tp_descr_set */
    0,                                                 /* tp_dictoffset */
    0,                                                 /* tp_init */
    0,                                                 /* tp_alloc */
    pycamera_new,                                      /* tp_new */
};

定义 pycamera 类型,包括其方法、内存分配、释放和其他行为。

pywindow.h 包括
#include <python.h>
#include <structmember.h>
#include "camerapreview.h"
  • python.h:使用 python c api 所需的。
  • structmember.h:提供管理对象成员的宏。
  • camerapreview.h:定义camerawindow类,用于显示相机预览并与其交互。
pywindow 结构体定义
typedef struct
{
    pyobject_head camerawindow *handler;
} pywindow;

定义一个包装 c camerawindow 对象的 pywindow 结构体。 handler 成员指向 camerawindow 的一个实例。

pywindow 对象的方法
  • pywindow_dealloc

    static int pywindow_clear(pywindow *self)
    {
        if (self-&gt;handler)
        {
            delete self-&gt;handler;
        }
        return 0;
    }
    
    static void pywindow_dealloc(pywindow *self)
    {
        pywindow_clear(self);
        py_type(self)-&gt;tp_free((pyobject *)self);
    }
    
    

    取消分配camerawindow对象并释放内存。

  • pywindow_new

    static pyobject *pywindow_new(pytypeobject *type, pyobject *args, pyobject *kwds)
    {
        pywindow *self;
    
        int width = 0, height = 0;
        char *title = null;
    
        if (!pyarg_parsetuple(args, "iis", &amp;width, &amp;height, &amp;title))
        {
            return null;
        }
    
        self = (pywindow *)type-&gt;tp_alloc(type, 0);
        if (self != null)
        {
            self-&gt;handler = new camerawindow(width, height, title);
    
            if (!self-&gt;handler-&gt;create())
            {
                std::cerr handler-&gt;show();
        }
    
        return (pyobject *)self;
    }
    
    

    创建 pywindow 的新实例。它为python对象分配内存,创建一个新的camerawindow对象,并将其分配给self->handler。

  • 等待键

    static pyobject *waitkey(pyobject *obj, pyobject *args)
    {
        pywindow *self = (pywindow *)obj;
    
        const char *key = null;
    
        if (!pyarg_parsetuple(args, "s", &amp;key) || strlen(key) != 1)
        {
            pyerr_setstring(pyexc_valueerror, "expected a single character string");
            return null;
        }
    
        bool ret = self-&gt;handler-&gt;waitkey(key[0]);
        return py_buildvalue("i", ret);
    }
    
    

    等待按键事件,如果按键与指定字符匹配则返回 false。 false 意味着应用程序应该退出。

  • showframe

    static pyobject *showframe(pyobject *obj, pyobject *args)
    {
        pywindow *self = (pywindow *)obj;
    
        int width = 0, height = 0;
        pyobject *bytearray = null;
    
        if (!pyarg_parsetuple(args, "iio", &amp;width, &amp;height, &amp;bytearray))
        {
            return null;
        }
    
        unsigned char *data = (unsigned char *)pybytearray_asstring(bytearray);
    
        self-&gt;handler-&gt;showframe(data, width, height);
    
        py_return_none;
    }
    
    

    在窗口中显示一个框架。

  • 绘制轮廓

    static pyobject *drawcontour(pyobject *obj, pyobject *args)
    {
        pywindow *self = (pywindow *)obj;
    
        pyobject *pypoints = null;
    
        if (!pyarg_parsetuple(args, "o", &amp;pypoints))
        {
            return null;
        }
    
        std::vector<:pair int>&gt; points;
    
        for (py_ssize_t i = 0; i handler-&gt;drawcontour(points);
    
        py_return_none;
    }
    
    </:pair>

    在框架上绘制轮廓(一系列点)。

  • 绘制文本

    static pyobject *drawtext(pyobject *obj, pyobject *args)
    {
        pywindow *self = (pywindow *)obj;
    
        const char *text = null;
        int x = 0, y = 0, fontsize = 0;
        pyobject *pycolor = null;
    
        if (!pyarg_parsetuple(args, "siiio", &amp;text, &amp;x, &amp;y, &amp;fontsize, &amp;pycolor))
        {
            return null;
        }
    
        camerawindow::color color;
        color.r = (unsigned char)pylong_aslong(pytuple_getitem(pycolor, 0));
        color.g = (unsigned char)pylong_aslong(pytuple_getitem(pycolor, 1));
        color.b = (unsigned char)pylong_aslong(pytuple_getitem(pycolor, 2));
    
        self-&gt;handler-&gt;drawtext(text, x, y, fontsize, color);
    
        py_return_none;
    }
    
    

    在框架上绘制文本。

窗口实例方法
static pymethoddef window_instance_methods[] = {
    {"waitkey", waitkey, meth_varargs, null},
    {"showframe", showframe, meth_varargs, null},
    {"drawcontour", drawcontour, meth_varargs, null},
    {"drawtext", drawtext, meth_varargs, null},
    {null, null, 0, null}};

定义 pywindow python 对象上可用的方法。

pywindow类型
static pytypeobject pywindowtype = {
    pyvarobject_head_init(null, 0) "litecam.pywindow", /* tp_name */
    sizeof(pywindow),                                  /* tp_basicsize */
    0,                                                 /* tp_itemsize */
    (destructor)pywindow_dealloc,                      /* tp_dealloc */
    0,                                                 /* tp_print */
    0,                                                 /* tp_getattr */
    0,                                                 /* tp_setattr */
    0,                                                 /* tp_reserved */
    0,                                                 /* tp_repr */
    0,                                                 /* tp_as_number */
    0,                                                 /* tp_as_sequence */
    0,                                                 /* tp_as_mapping */
    0,                                                 /* tp_hash  */
    0,                                                 /* tp_call */
    0,                                                 /* tp_str */
    pyobject_genericgetattr,                           /* tp_getattro */
    pyobject_genericsetattr,                           /* tp_setattro */
    0,                                                 /* tp_as_buffer */
    py_tpflags_default | py_tpflags_basetype,          /*tp_flags*/
    "pywindow",                                        /* tp_doc */
    0,                                                 /* tp_traverse */
    0,                                                 /* tp_clear */
    0,                                                 /* tp_richcompare */
    0,                                                 /* tp_weaklistoffset */
    0,                                                 /* tp_iter */
    0,                                                 /* tp_iternext */
    window_instance_methods,                           /* tp_methods */
    0,                                                 /* tp_members */
    0,                                                 /* tp_getset */
    0,                                                 /* tp_base */
    0,                                                 /* tp_dict */
    0,                                                 /* tp_descr_get */
    0,                                                 /* tp_descr_set */
    0,                                                 /* tp_dictoffset */
    0,                                                 /* tp_init */
    0,                                                 /* tp_alloc */
    pywindow_new,                                      /* tp_new */
};

定义 pywindow 类型,包括其方法、内存分配、释放和其他行为。

litecam.cpp
#include <python.h>

#include <stdio.h>

#include "pycamera.h"
#include "pywindow.h"

#define initerror return null

static pyobject *getdevicelist(pyobject *obj, pyobject *args)
{
    pyobject *pylist = pylist_new(0);

    std::vector<capturedeviceinfo> devices = listcapturedevices();

    for (size_t i = 0; i < devices.size(); i++)
    {
        capturedeviceinfo &device = devices[i];

#ifdef _win32
        pyobject *pyname = pyunicode_fromwidechar(device.friendlyname, wcslen(device.friendlyname));
        if (pyname != null)
        {
            pylist_append(pylist, pyname);
            py_decref(pyname);
        }
#else
        pyobject *pyname = pyunicode_fromstring(device.friendlyname);
        if (pyname != null)
        {
            pylist_append(pylist, pyname);
            py_decref(pyname);
        }
#endif
    }

    return pylist;
}

static pyobject *savejpeg(pyobject *obj, pyobject *args)
{
    const char *filename = null;
    int width = 0, height = 0;
    pyobject *bytearray = null;

    if (!pyarg_parsetuple(args, "siio", &filename, &width, &height, &bytearray))
    {
        pyerr_setstring(pyexc_typeerror, "expected arguments: str, int, int, pybytearray");
        return null;
    }

    unsigned char *data = (unsigned char *)pybytearray_asstring(bytearray);
    py_ssize_t size = pybytearray_size(bytearray);

    if (size != (py_ssize_t)(width * height * 3))
    {
        pyerr_setstring(pyexc_valueerror, "invalid byte array size for the given width and height.");
        return null;
    }

    saveframeasjpeg(data, width, height, filename);

    py_return_none;
}

static pymethoddef litecam_methods[] = {
    {"getdevicelist", getdevicelist, meth_varargs, "get available cameras"},
    {"savejpeg", savejpeg, meth_varargs, "get available cameras"},
    {null, null, 0, null}};

static struct pymoduledef litecam_module_def = {
    pymoduledef_head_init,
    "litecam",
    "internal "litecam" module",
    -1,
    litecam_methods};

pymodinit_func pyinit_litecam(void)
{
    pyobject *module = pymodule_create(&litecam_module_def);
    if (module == null)
        initerror;

    if (pytype_ready(&pycameratype) < 0)
    {
        printf("failed to initialize pycameratype
");
        py_decref(module);
        return null;
    }

    if (pymodule_addobject(module, "pycamera", (pyobject *)&pycameratype) < 0)
    {
        printf("failed to add pycamera to the module
");
        py_decref(&pycameratype);
        py_decref(module);
        initerror;
    }

    if (pytype_ready(&pywindowtype) < 0)
    {
        printf("failed to initialize pywindowtype
");
        py_decref(module);
        return null;
    }

    if (pymodule_addobject(module, "pywindow", (pyobject *)&pywindowtype) < 0)
    {
        printf("failed to add pywindow to the module
");
        py_decref(&pywindowtype);
        py_decref(module);
        initerror;
    }

    return module;
}

说明:

  • getdevicelist:返回可用摄像头的列表。
  • savejpeg:将帧保存为 jpeg 图像。
  • pyinit_litecam:初始化litecam模块并注册pycamera和pywindow类型。
构建 python 相机 sdk
  • 开发模式

    python setup.py develop
    
  • 轮组

    python setup.py bdist_wheel
    
  • 来源分布

    python setup.py sdist
    
实现 python 多条码扫描器的步骤
  1. 安装python相机sdk和dynamsoft barcode reader sdk:

    pip install lite-camera dynamsoft-capture-vision-bundle
    
  2. 获取 dynamsoft barcode reader 30 天免费试用许可证。

  3. 创建用于多条码扫描的 python 脚本:

    import litecam
    from dynamsoft_capture_vision_bundle import *
    import queue
    
    class framefetcher(imagesourceadapter):
        def has_next_image_to_fetch(self) -&gt; bool:
            return true
    
        def add_frame(self, imagedata):
            self.add_image_to_buffer(imagedata)
    
    class mycapturedresultreceiver(capturedresultreceiver):
        def __init__(self, result_queue):
            super().__init__()
            self.result_queue = result_queue
    
        def on_captured_result_received(self, captured_result):
            self.result_queue.put(captured_result)
    
    if __name__ == '__main__':
        errorcode, errormsg = licensemanager.init_license(
            "license-key")
        if errorcode != enumerrorcode.ec_ok and errorcode != enumerrorcode.ec_license_cache_used:
            print("license initialization failed: errorcode:",
                  errorcode, ", errorstring:", errormsg)
        else:
            camera = litecam.pycamera()
            if camera.open(0):
    
                cvr = capturevisionrouter()
                fetcher = framefetcher()
                cvr.set_input(fetcher)
    
                result_queue = queue.queue()
    
                receiver = mycapturedresultreceiver(result_queue)
                cvr.add_result_receiver(receiver)
    
                errorcode, errormsg = cvr.start_capturing(
                    enumpresettemplate.pt_read_barcodes.value)
    
                if errorcode != enumerrorcode.ec_ok:
                    print("error:", errormsg)
    
                window = litecam.pywindow(
                    camera.getwidth(), camera.getheight(), "camera stream")
    
                while window.waitkey('q'):
                    frame = camera.captureframe()
                    if frame is not none:
                        width = frame[0]
                        height = frame[1]
                        size = frame[2]
                        data = frame[3]
                        window.showframe(width, height, data)
    
                        imagedata = imagedata(
                            bytes(data), width, height, width * 3, enumimagepixelformat.ipf_rgb_888)
                        fetcher.add_frame(imagedata)
    
                        if not result_queue.empty():
                            captured_result = result_queue.get_nowait()
    
                            items = captured_result.get_items()
                            for item in items:
    
                                if item.get_type() == enumcapturedresultitemtype.crit_barcode:
                                    text = item.get_text()
                                    location = item.get_location()
                                    x1 = location.points[0].x
                                    y1 = location.points[0].y
                                    x2 = location.points[1].x
                                    y2 = location.points[1].y
                                    x3 = location.points[2].x
                                    y3 = location.points[2].y
                                    x4 = location.points[3].x
                                    y4 = location.points[3].y
    
                                    contour_points = [
                                        (x1, y1), (x2, y2), (x3, y3), (x4, y4)]
                                    window.drawcontour(contour_points)
    
                                    window.drawtext(text, x1, y1, 24, (255, 0, 0))
    
                                    del location
    
                camera.release()
    
                cvr.stop_capturing()
    
    

    将 license-key 替换为您的 dynamsoft barcode reader 许可证密钥。

  4. 运行脚本:

    python main.py
    

    python multi-barcode scanner

源代码

https://github.com/yushulx/python-lite-camera

以上就是构建 Python 相机 SDK 并使用它进行多条码扫描的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • 华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀

    华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀
    华为 mate 70 或将首发麒麟新款处理器,并将此前有博主爆料其性能跑分将突破110万,这意味着 mate 70 性能将重新夺回第一梯队。也因此,苹果 iphone 16 唯一能有一战之力的性能,也要被 mate 70 拉近不少了。 据悉,华为 Mate 70 性能会大幅提升,并且销量相比 Mate 60 预计增长40% - 50%,且备货充足。如果 iPhone 16 发售日期与 Mate 70 重合,销量很可能被瞬间抢购。 不过,iPhone 16 还有一个阵地暂时难...
  • 酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元

    酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元
    本站 5 月 16 日消息,酷凛 id-cooling 近日推出霜界 240/360 一体式水冷散热器,采用黑色无光低调设计,分别定价 239/279 元。 本站整理霜界 240/360 散热器规格如下: 酷凛宣称这两款水冷散热器搭载“自研新 V7 水泵”,采用三相六极马达和改进的铜底方案,缩短了水流路径,相较上代水泵进一步提升解热能力。 霜界 240/360 散热器的水泵为定速 2800 RPM 设计,噪声 28db (A)。 两款一体式水冷散热器采用 27mm 厚冷排,...
  • 惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起

    惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起
    本站 5 月 14 日消息,继上线官网后,新款惠普战 99 商用笔记本现已上架,搭载酷睿 ultra / 锐龙 8040处理器,最高可选英伟达rtx 3000 ada 独立显卡,售价 4999 元起。 战 99 锐龙版 R7-8845HS / 16GB / 1TB:4999 元 R7-8845HS / 32GB / 1TB:5299 元 R7-8845HS / RTX 4050 / 32GB / 1TB:7299 元 R7 Pro-8845HS / RTX 2000 Ada...
  • python中def什么意思

    python中def什么意思
    python 中,def 关键字用于定义函数,这些函数是代码块,执行特定任务。函数语法为 def (参数列表)。函数可以通过其名字和圆括号调用。函数可以接受参数作为输入,并在函数体中使用参数名访问。函数可以使用 return 语句返回一个值,它将成为函数调用的结果。 Python 中 def 关键字 在 Python 中,def 关键字用于定义函数。函数是代码块,旨在执行特定任务。 语法 def 函数定义的语法如下: def (参数列表): # 函数体 示例 定义...
  • python怎么调用其他文件函数

    python怎么调用其他文件函数
    在 python 中调用其他文件中的函数,有两种方式:1. 使用 import 语句导入模块,然后调用 [模块名].[函数名]();2. 使用 from ... import 语句从模块导入特定函数,然后调用 [函数名]()。 如何在 Python 中调用其他文件中的函数 在 Python 中,您可以通过以下两种方式调用其他文件中的函数: 1. 使用 import 语句 优点:简单且易于使用。 缺点:会将整个模块导入到当前作用域中,可能会导致命名空间混乱。 步骤:...