C# 9/10 .net 6 中基于网络摄像头的对象扫描仪

Webcam based object Scanner in C# 9/10 .net 6

我正在尝试将此 Python 代码从 theDataFox card_scanner_app 移植到 C# WPF 应用程序。

Python 程序使用网络摄像头识别对象(交易卡)并通过按 Space 栏为对象拍摄快照。 据我所知,代码对快照进行哈希处理并将其与 64.000 个图像的数据库进行比较,这些图像已经被哈希处理。

然后代码使用在图像文件名中给出的图像 ID,并从数据库生成包含有关此特定对象的所有信息的输出。

import cv2
import pygame
import imutils
import numpy as np
import pygame.camera
from pygame.locals import KEYDOWN, K_q, K_s, K_SPACE
from . import util
import argparse
import glob

DEBUG = False

# calibrate this for camera position
MIN_CARD_AREA = 250000.0 / 3

# calibrate these
THRESHOLD = (100, 255)
FILTER = (11, 17, 17)

ROTATION = 0

# noinspection PyUnresolvedReferences
def scan(img):
    # preprocess image
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.bilateralFilter(gray, FILTER[0], FILTER[1], FILTER[2])
    ret, gray = cv2.threshold(gray, THRESHOLD[0], THRESHOLD[1], cv2.THRESH_BINARY)
    edges = imutils.auto_canny(gray)

# extract contours
cnts, _ = cv2.findContours(edges.copy(), cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = [c for c in cnts if cv2.contourArea(c) >= MIN_CARD_AREA]

card, c = None, None
if cnts:
    # get largest contour
    c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]

    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.05 * peri, True)
    pts = np.float32(approx)

    x, y, w, h = cv2.boundingRect(c)

    # Find center point of card by taking x and y average of the four corners.
    # average = np.sum(pts, axis=0)/len(pts)
    # cent_x = int(average[0][0])
    # cent_y = int(average[0][1])
    # center = [cent_x, cent_y]

    # Warp card into 200x300 flattened image using perspective transform
    card = util.flattener(img, pts, w, h)
    card = util.cv2_to_pil(card).rotate(ROTATION)
return card, c, gray, edges


# noinspection PyUnresolvedReferences
def detect(on_detect):
    dim = (800, 600)
    pygame.init()
    pygame.camera.init()
    cams = pygame.camera.list_cameras()
# print(cams)
display = pygame.display.set_mode(dim, 0)
cam = pygame.camera.Camera(cams[-1], dim)
cam.start()


capture = True
while capture:
    img = cam.get_image()
    img = pygame.transform.scale(img, dim)
    img = util.pygame_to_cv2(img)
    card, c, gray, edges = scan(img)


    # q to quit
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_q:
                capture = False
            elif event.key == K_s or event.key == K_SPACE:
                if card is None:
                    print('nothing found')
                else:
                    on_detect(card)

    # display
    if c is not None:
       cv2.drawContours(img, [c], -1, (0, 0, 255), 3)
    img = util.cv2_to_pygame(img)
    display.blit(img, (0, 0))
    pygame.display.update()

    if card is not None:
        card_img = util.pil_to_pygame(card)
        display.blit(card_img, (0, 0))

    if DEBUG:
        for layer in [gray, edges]:
            layer = cv2.cvtColor(layer, cv2.COLOR_GRAY2RGB)
            layer = util.cv2_to_pygame(layer)
            layer.set_alpha(100)
        display.blit(layer, (0, 0))

    pygame.display.flip()

cam.stop()
pygame.quit()

现在我正试图找到一个解决方案来使用 C# 获得类似的网络摄像头访问 (Visual Studio)。

至于我还是初学者,我不知道该怎么做。

我尝试了几个 NuGet 包,但没有任何效果。估计是我技术不够好。

因此我现在不得不问你,你有什么想法或解决方案可以完成给定的任务吗?

我已经移植了大部分程序,并且运行良好。 This is my full Code

没有直接在c#中内置的网络摄像头api,最接近的是UWP video capture API。当我尝试这个时,它在我的网络摄像头上工作得不是很好,但那可能只是我。

有很多内置网络摄像头支持的图像处理库。这包括 OpenCV/emguCV, but also for example aforge

我使用了“versatile webcam library”,它是原生网络摄像头 API 的包装器,它似乎运行良好。

或多或少,所有库都有很好的文档和很好的示例如何获取图像,许多库还有演示如何使用库的示例应用程序,这应该足以帮助您入门。所以“我试过了,但没有用”并不是一个好的解释。 你试过什么为什么没用?