python - 使用 OpenCV 识别 7 段显示器上的数字
问题描述
我正在尝试识别 7 段显示器上的数字。
我在 Jupyter notebook 上使用 python。
我有 0~9 7 段显示的数字图像,每个数字都带有 . 分别保存。下面是3
, 3.
, 2
,的示例图片2.
我想在目标图像上找到这些图像。
我听说有工具可以找到类似的图像OpenCV
。
我尝试使用 SIFT 描述符和比率测试进行蛮力匹配, 但输出似乎不准确。
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
img1 = cv2.imread('C:\\Users\\USER\\Desktop\\test\\deeplearningimage\\thermo\\3..png',cv2.IMREAD_GRAYSCALE) # trainImage
img2 = cv2.imread('C:\\Users\\USER\\Desktop\\test\\thermosample.jpg',cv2.IMREAD_GRAYSCALE) # queryImage
# Initiate SIFT detector
sift = cv.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1,des2,k=2)
# Apply ratio test
good = []
for m,n in matches:
if m.distance < 0.75*n.distance:
good.append([m])
# cv.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1,kp1,img2,kp2,good,None,flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
plt.imshow(img3),plt.show()'
这是上面代码的输出
不知道如何进行。还有其他opencv
可以解决这个问题的吗?
解决方案
import numpy as np
import matplotlib.pyplot as plt
import cv2
# Read Image
BGR = cv2.imread('input.jpg')
RGB = cv2.cvtColor(BGR, cv2.COLOR_BGR2RGB)
# Channels split
R = BGR[...,2]
G = BGR[...,1]
B = BGR[...,0]
# Threshold per channel
R[B>120] = 0
R[G>120] = 0
R[R<230] = 0
# Binarize
Binary = cv2.threshold(R, 127, 255, cv2.THRESH_BINARY)[1]
# Edge Detection
Edges = cv2.Canny(Binary, 50, 200)
# Read Template
templBGR = cv2.imread('templ.png')
templRGB = cv2.cvtColor(templBGR, cv2.COLOR_BGR2RGB)
templateGray = cv2.cvtColor(templBGR, cv2.COLOR_BGR2GRAY)
# Binarize Template
templateBinary = cv2.threshold(templateGray, 84, 255, cv2.THRESH_BINARY)[1]
# Denoise Template
templateFiltered = cv2.medianBlur(templateBinary,7)
# Resize Template
template = cv2.resize(templateFiltered, (templBGR.shape[1]//2, templBGR.shape[0]//2))
# Edge Detection Template
templateEdges = cv2.Canny(template, 50, 200)
# Extract Dimensions
h, w = template.shape
res = cv2.matchTemplate(Edges,templateEdges,cv2.TM_CCORR)
(_, _, _, maxLoc) = cv2.minMaxLoc(res)
img = RGB.copy()
cv2.rectangle(img, (maxLoc[0], maxLoc[1]), (maxLoc[0] + w, maxLoc[1] + h), (255,255,128), 2)
plt.subplot(221)
plt.imshow(RGB)
plt.title('Original')
plt.axis('off')
plt.subplot(222)
plt.imshow(Edges, cmap='gray')
plt.title('Segmented')
plt.axis('off')
plt.subplot(223)
plt.imshow(templRGB)
plt.title('Template')
plt.axis('off')
plt.subplot(224)
plt.imshow(img)
plt.title('Result')
plt.axis('off')
plt.show()
如果您想更好地进行多重匹配,请使用循环:
threshold = 0.8
Loc = np.where( res >= threshold)
for pt in zip(*Loc):
cv2.rectangle(img, (Loc[0], Loc[1]), (Loc[0] + w, Loc[1] + h), (255,255,128), 2)
推荐阅读
- java - 返回带有文件源的对象流
- r - 从一组所有可能的组合中抽取 10 个项目中的 3 个,如何获取每个组合对应的未选中项目?
- python - 如何生成身份验证令牌以限制外部查询对我的服务器的访问
- github - 您无权在 Github 上推送。您想创建一个分叉并改为推送它吗
- c++ - C++ 代码中使用的 C 结构生成错误“调用隐式删除...”
- clojure - Clojure 规范 - 向用户显示好的错误消息的方法
- html - 如何使用纯 CSS 沿 HTML 选择中的选定选项附加一个勾号图标
- react-native - 我在使用 expo 应用程序在物理设备上进行 react-native 工作时遇到了一些问题
- javascript - 如何让我的输入值显示在我的应用程序中,而不是显示为警报?
- apache-kafka - 如何在 Apache Beam 中使用带有 protobuf 定义的 Kafka 消息?