备注
我是OpenCV(或计算机视觉)的新手,所以告诉我搜索查询会很有帮助!
我想问的是
我想写一个从图片中提取名片的程序。我能够提取一个粗略的轮廓,但反射的光变成了噪声,我无法提取准确的轮廓。请告诉我你的想法。
图像(原始数据)
输出
代码
import math
import itertools
from glob import glob
import cv2
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
%matplotlib inline
def read_images():
"read image data from data directory"
names = glob('data/*.jpg')
names.sort()
return map(lambda name: cv2.imread(name), names)
def blur(img):
"apply blur"
return cv2.GaussianBlur(img, (25, 25), 0)
def show_images(images, column, color_type=cv2.COLOR_BGR2RGB):
"plot images with matplotlib"
plt.figure(figsize=(10,10), dpi=150)
for n, img in zip(range(len(images)), images):
p = plt.subplot(math.ceil(len(images) / column), column, n + 1)
p.axis('off')
if color_type is None:
p.imshow(img)
else:
p.imshow(cv2.cvtColor(img, color_type))
plt.show()
def detect_background_color(img):
"detect background color"
# Assume that the perimeter is all background
height, width, *_ = img.shape
background_colors = np.concatenate([
img[5:height-5, 5], img[5, 5:width-5],
img[5:height-5, width-5], img[height-5, 5:width-5]
])
background_colors = background_colors.astype(np.float32)
# Assume that the background color is only one.
K = 2
iter_flg = cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER
_, labels, centers = cv2.kmeans(
background_colors, K, None, (iter_flg, 10, 1.0), 10,
cv2.KMEANS_RANDOM_CENTERS)
cnt1 = len(labels[labels==0])
cnt2 = len(labels[labels==1])
return centers[0] if cnt1 > cnt2 else centers[1]
def scale(img):
bg = detect_background_color(img)
return np.fix(np.sqrt(np.sum(np.square(img - bg), axis=2)) / 1.732).astype(np.uint8)
def binarize(img):
th, bit = cv2.threshold(img, 40, 255, cv2.THRESH_BINARY)
return bit
binarized = [binarize(scale(blur(img))) for img in read_images()]
show_images(binarized, 4, None)发布于 2020-10-08 17:58:03
看起来你需要应用形态学,尝试cv2.erode,然后cv2扩展操作。第一次将删除小于侵蚀内核大小的区域,第二次将恢复较大斑点的初始大小。您需要为这两个操作应用相同大小的内核。morphology。
还要检查这个:medium article
https://stackoverflow.com/questions/64259055
复制相似问题