首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >[OpenCV]如何将轮廓固定为矩形?

[OpenCV]如何将轮廓固定为矩形?
EN

Stack Overflow用户
提问于 2020-10-08 16:54:38
回答 1查看 61关注 0票数 0

备注

我是OpenCV(或计算机视觉)的新手,所以告诉我搜索查询会很有帮助!

我想问的是

我想写一个从图片中提取名片的程序。我能够提取一个粗略的轮廓,但反射的光变成了噪声,我无法提取准确的轮廓。请告诉我你的想法。

图像(原始数据)

raw data

输出

output data(rough outline)

代码

代码语言:javascript
复制
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)
EN

回答 1

Stack Overflow用户

发布于 2020-10-08 17:58:03

看起来你需要应用形态学,尝试cv2.erode,然后cv2扩展操作。第一次将删除小于侵蚀内核大小的区域,第二次将恢复较大斑点的初始大小。您需要为这两个操作应用相同大小的内核。morphology

还要检查这个:medium article

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64259055

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档