Heim >Backend-Entwicklung >Python-Tutorial >Erstellen eines Python-Kamera-SDK und dessen Verwendung zum Scannen mehrerer Barcodes

Erstellen eines Python-Kamera-SDK und dessen Verwendung zum Scannen mehrerer Barcodes

Linda Hamilton
Linda HamiltonOriginal
2025-01-05 01:35:40313Durchsuche

Da das leichte C-Kamera-SDK nun für Windows, Linux und macOS fertig ist, können wir es in andere höhere Programmiersprachen integrieren. In diesem Artikel erfahren Sie, wie Sie ein Python-Kamera-SDK basierend auf der C-Kamerabibliothek erstellen und es für das Scannen mehrerer Barcodes mit dem Dynamsoft Barcode Reader SDK verwenden.

Demovideo zum Python-Multi-Barcode-Scanner

Gerüstbau für ein CPython-Erweiterungsprojekt

Eine CPython-Erweiterung ist eine gemeinsam genutzte Bibliothek (z. B. eine DLL unter Windows, eine .so unter Linux oder eine .dylib unter macOS), die kann zur Laufzeit in den Python-Interpreter geladen und zur Erweiterung seiner Funktionalität verwendet werden. Die Struktur des CPython-Erweiterungsprojekts für die Lite-Kamera ist wie folgt:

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

Erklärung:

  • Dazu gehören: Die Header-Dateien der C-Kamerabibliothek.
  • lib: Die gemeinsam genutzten Bibliotheken der C-Kamerabibliothek.
  • src: Der Quellcode des Python-Kamera-SDK.
  • litecam: Der Einstiegspunkt der Python-Erweiterung.
  • setup.py: Das Build-Skript.
  • MANIFEST.in: Die Manifestdatei zum Einschließen von Nicht-Python-Dateien.
  • README.md: Die Dokumentation.

Schreiben des Build-Skripts setup.py für die Python-Erweiterung

Fügen Sie den folgenden Inhalt zu setup.py hinzu:

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},
      )

Erklärung:

  • lite-camera: Der Name des Python-Pakets.
  • ext_modules: Eine Liste von CPython-Erweiterungen. Es gibt die Quelldateien, Include-Verzeichnisse, Bibliotheksverzeichnisse, Bibliotheken und Kompilierungs-/Link-Flags für verschiedene Plattformen an.
  • entwickeln: Ein benutzerdefinierter Befehl für die Entwicklung. Es kopiert die gemeinsam genutzten Bibliotheken zum einfachen Testen in den Litecam-Ordner.
  • build_ext: Passt den Build-Prozess zum Packen der gemeinsam genutzten Bibliotheken in das Wheel-Paket an.

Implementierung der Python Camera SDK API in C

Die Datei pycamera.h definiert die Python-Klasse PyCamera zum Erfassen von Bildern von der Kamera, während die Datei pywindow.h die Python-Klasse PyWindow zum Anzeigen der Bilder in einem Fenster definiert. Die Datei litecam.cpp dient als Einstiegspunkt für die Python-Erweiterung, in der einige globale Methoden definiert und die Klassen PyCamera und PyWindow registriert werden.

pycamera.h

Inklusive

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
  • Python.h: Enthalten, um die Python-C-API zu verwenden.
  • structmember.h: Stellt Makros und Helfer zum Verwalten von Objektmitgliedern bereit.
  • Camera.h: Definiert die Kameraklasse, die von der PyCamera-Erweiterung umschlossen wird.

PyCamera-Strukturdefinition

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},
      )

Die PyCamera-Struktur stellt das Python-Objekt dar, das das C-Kameraobjekt umschließt. Der Handler ist ein Zeiger auf eine Instanz der Kameraklasse.

Methoden

  • PyCamera_dealloc

    #include <Python.h>
    #include <structmember.h>
    #include "Camera.h"
    

    Gibt die Zuordnung des Kameraobjekts frei und gibt den zugehörigen Speicher frei.

  • PyCamera_new

    typedef struct
    {
        PyObject_HEAD Camera *handler;
    } PyCamera;
    

    Erstellt eine neue Instanz von PyCamera. Es reserviert Speicher für das Python-Objekt, erstellt ein neues Kameraobjekt und weist es dem Self->-Handler zu.

  • geöffnet

    static int PyCamera_clear(PyCamera *self)
    {
        if (self->handler)
        {
            delete self->handler;
        }
        return 0;
    }
    
    static void PyCamera_dealloc(PyCamera *self)
    {
        PyCamera_clear(self);
        Py_TYPE(self)->tp_free((PyObject *)self);
    }
    
    

    Öffnet die Kamera mit dem angegebenen Index.

  • listMediaTypes

    static PyObject *PyCamera_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
    {
        PyCamera *self;
    
        self = (PyCamera *)type->tp_alloc(type, 0);
        if (self != NULL)
        {
            self->handler = new Camera();
        }
    
        return (PyObject *)self;
    }
    
    

    Gibt eine Liste der unterstützten Medientypen zurück. Für Windows konvertiert es die breite Zeichenfolge in ein Python-Unicode-Objekt.

  • Veröffentlichung

    static PyObject *open(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        int index = 0;
        if (!PyArg_ParseTuple(args, "i", &index))
        {
            return NULL;
        }
    
        bool ret = self->handler->Open(index);
        return Py_BuildValue("i", ret);
    }
    

    Gibt die Kamera frei.

  • setResolution

    static PyObject *listMediaTypes(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        std::vector<MediaTypeInfo> mediaTypes = self->handler->ListSupportedMediaTypes();
    
        PyObject *pyList = PyList_New(0);
    
        for (size_t i = 0; i < mediaTypes.size(); i++)
        {
            MediaTypeInfo &mediaType = mediaTypes[i];
    
    #ifdef _WIN32
            PyObject *subtypeName = PyUnicode_FromWideChar(mediaType.subtypeName, wcslen(mediaType.subtypeName));
            PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:O}",
                                                  "width", mediaType.width,
                                                  "height", mediaType.height,
                                                  "subtypeName", subtypeName);
            if (subtypeName != NULL)
            {
                Py_DECREF(subtypeName);
            }
    
    #else
            PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:s}",
                                                  "width", mediaType.width,
                                                  "height", mediaType.height,
                                                  "subtypeName", mediaType.subtypeName);
    #endif
    
            PyList_Append(pyList, pyMediaType);
        }
    
        return pyList;
    }
    
    

    Stellt die Auflösung der Kamera ein.

  • captureFrame

    static PyObject *release(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        self->handler->Release();
        Py_RETURN_NONE;
    }
    

    Erfasst ein Bild von der Kamera und gibt die RGB-Daten als Python-Byte-Array zurück.

  • getWidth und getHeight

    static PyObject *setResolution(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
        int width = 0, height = 0;
        if (!PyArg_ParseTuple(args, "ii", &width, &height))
        {
            return NULL;
        }
        int ret = self->handler->SetResolution(width, height);
        return Py_BuildValue("i", ret);
    }
    

    Gibt die Breite und Höhe des erfassten Rahmens zurück.

Instanz_Methoden

static PyObject *captureFrame(PyObject *obj, PyObject *args)
{
    PyCamera *self = (PyCamera *)obj;

    FrameData frame = self->handler->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;
    }
}

Definiert die Methoden, die für das PyCamera-Python-Objekt verfügbar sind. Diese Methoden sind mit den entsprechenden oben definierten C-Funktionen verknüpft.

PyCameraType

static PyObject *getWidth(PyObject *obj, PyObject *args)
{
    PyCamera *self = (PyCamera *)obj;

    int width = self->handler->frameWidth;
    return Py_BuildValue("i", width);
}

static PyObject *getHeight(PyObject *obj, PyObject *args)
{
    PyCamera *self = (PyCamera *)obj;

    int height = self->handler->frameHeight;
    return Py_BuildValue("i", height);
}

Definiert den PyCamera-Typ, einschließlich seiner Methoden, Speicherzuweisung, Freigabe und anderen Verhaltensweisen.

pywindow.h

Inklusive

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}};

  • Python.h: Erforderlich für die Verwendung der Python-C-API.
  • structmember.h: Stellt Makros zum Verwalten von Objektmitgliedern bereit.
  • CameraPreview.h: Definiert die CameraWindow-Klasse, die zur Anzeige einer Kameravorschau und zur Interaktion mit dieser verwendet wird.

PyWindow-Strukturdefinition

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 */
};

Definiert eine PyWindow-Struktur, die ein C-CameraWindow-Objekt umschließt. Das Handler-Member zeigt auf eine Instanz von CameraWindow.

Methoden für das PyWindow-Objekt

  • PyWindow_dealloc

    #include <Python.h>
    #include <structmember.h>
    #include "CameraPreview.h"
    

    Gibt die Zuordnung des CameraWindow-Objekts frei und gibt den Speicher frei.

  • PyWindow_new

    typedef struct
    {
        PyObject_HEAD CameraWindow *handler;
    } PyWindow;
    
    

    Erstellt eine neue Instanz von PyWindow. Es reserviert Speicher für das Python-Objekt, erstellt ein neues CameraWindow-Objekt und weist es dem Self->-Handler zu.

  • waitKey

    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
    

    Wartet auf ein Tastendruckereignis und gibt False zurück, wenn die Taste mit dem angegebenen Zeichen übereinstimmt. „Falsch“ bedeutet, dass die Anwendung beendet werden sollte.

  • showFrame

    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},
          )
    

    Zeigt einen Rahmen im Fenster an.

  • drawContour

    #include <Python.h>
    #include <structmember.h>
    #include "Camera.h"
    

    Zeichnet eine Kontur (eine Reihe von Punkten) auf dem Rahmen.

  • drawText

    typedef struct
    {
        PyObject_HEAD Camera *handler;
    } PyCamera;
    

    Zeichnet Text auf den Rahmen.

window_instance_methods

static int PyCamera_clear(PyCamera *self)
{
    if (self->handler)
    {
        delete self->handler;
    }
    return 0;
}

static void PyCamera_dealloc(PyCamera *self)
{
    PyCamera_clear(self);
    Py_TYPE(self)->tp_free((PyObject *)self);
}

Definiert die Methoden, die für das PyWindow-Python-Objekt verfügbar sind.

PyWindowType

static PyObject *PyCamera_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyCamera *self;

    self = (PyCamera *)type->tp_alloc(type, 0);
    if (self != NULL)
    {
        self->handler = new Camera();
    }

    return (PyObject *)self;
}

Definiert den PyWindow-Typ, einschließlich seiner Methoden, Speicherzuweisung, Freigabe und anderem Verhalten.

litecam.cpp

static PyObject *open(PyObject *obj, PyObject *args)
{
    PyCamera *self = (PyCamera *)obj;

    int index = 0;
    if (!PyArg_ParseTuple(args, "i", &index))
    {
        return NULL;
    }

    bool ret = self->handler->Open(index);
    return Py_BuildValue("i", ret);
}

Erklärung:

  • getDeviceList: Gibt eine Liste der verfügbaren Kameras zurück.
  • saveJpeg: Speichert einen Frame als JPEG-Bild.
  • PyInit_litecam: Initialisiert das Litecam-Modul und registriert die Typen PyCamera und PyWindow.

Erstellen des Python-Kamera-SDK

  • Entwicklungsmodus

    static PyObject *listMediaTypes(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        std::vector<MediaTypeInfo> mediaTypes = self->handler->ListSupportedMediaTypes();
    
        PyObject *pyList = PyList_New(0);
    
        for (size_t i = 0; i < mediaTypes.size(); i++)
        {
            MediaTypeInfo &mediaType = mediaTypes[i];
    
    #ifdef _WIN32
            PyObject *subtypeName = PyUnicode_FromWideChar(mediaType.subtypeName, wcslen(mediaType.subtypeName));
            PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:O}",
                                                  "width", mediaType.width,
                                                  "height", mediaType.height,
                                                  "subtypeName", subtypeName);
            if (subtypeName != NULL)
            {
                Py_DECREF(subtypeName);
            }
    
    #else
            PyObject *pyMediaType = Py_BuildValue("{s:i,s:i,s:s}",
                                                  "width", mediaType.width,
                                                  "height", mediaType.height,
                                                  "subtypeName", mediaType.subtypeName);
    #endif
    
            PyList_Append(pyList, pyMediaType);
        }
    
        return pyList;
    }
    
    
  • Radpaket

    static PyObject *release(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        self->handler->Release();
        Py_RETURN_NONE;
    }
    
  • Quellenverteilung

    static PyObject *setResolution(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
        int width = 0, height = 0;
        if (!PyArg_ParseTuple(args, "ii", &width, &height))
        {
            return NULL;
        }
        int ret = self->handler->SetResolution(width, height);
        return Py_BuildValue("i", ret);
    }
    

Schritte zum Implementieren eines Python-Multi-Barcode-Scanners

  1. Installieren Sie das Python-Kamera-SDK und das Dynamsoft Barcode Reader SDK:

    static PyObject *captureFrame(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        FrameData frame = self->handler->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;
        }
    }
    
  2. Erhalten Sie eine 30-tägige kostenlose Testlizenz für Dynamsoft Barcode Reader.

  3. Erstellen Sie ein Python-Skript für das Scannen mehrerer Barcodes:

    static PyObject *getWidth(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        int width = self->handler->frameWidth;
        return Py_BuildValue("i", width);
    }
    
    static PyObject *getHeight(PyObject *obj, PyObject *args)
    {
        PyCamera *self = (PyCamera *)obj;
    
        int height = self->handler->frameHeight;
        return Py_BuildValue("i", height);
    }
    

    Ersetzen Sie LICENSE-KEY durch Ihren Dynamsoft Barcode Reader-Lizenzschlüssel.

  4. Führen Sie das Skript aus:

    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}};
    
    

    Building a Python Camera SDK and Using It for Multi-Barcode Scanning

Quellcode

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

Das obige ist der detaillierte Inhalt vonErstellen eines Python-Kamera-SDK und dessen Verwendung zum Scannen mehrerer Barcodes. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn