如何去除图像模糊的背景?

How to remove blurred background of images?

我正在做一个叶病分类的项目。我想使用高效的机器学习分割算法去除整个数据集的模糊背景。输出应该是 ROI 的彩色版本。由于数据集的数量巨大,我想要一种训练时间更少的算法。那么,你能建议我可以坚持的任何选择吗?

下面附有数据集示例。

leaf image with a disease symptom

这个特殊问题并不难解决。它并没有那么糟糕,因为只有一个前景对象,这意味着我们可以使用简单的方法解决它。 @Ceopee 的边缘检测直觉是正确的,因为它是前景与模糊背景不同的最明显方式。

我对图像进行了灰度处理并使用了 Canny 边缘检测器。我根本没有真正调整它,所以我们得到了一堆边缘,但我们只关心找到叶子的边缘。值得庆幸的是,我们不必花大量时间为每张图像调整它,因为我们只关心最大的连续边缘。

我放大图像以连接附近的边缘(canny 给出 1 像素宽的线条,这些线条很容易断开),然后使用 findContours 获得所有白线的轮廓。我按区域分类并选择最大的轮廓,然后使用它来创建蒙版。

蒙版的锯齿让我很困扰,所以我做了一个开运算(去除细锯齿),然后进行中值模糊(平滑边缘)。

然后用蒙版裁剪一下就大功告成了。 (我不得不将其更改为 jpg 以达到 2mb 的限制,因此此处可能存在一些压缩伪像)。

这是代码(请注意,这是在 OpenCV 3.4 中,如果您使用的是其他主要版本,则必须修改 findContours 行)

import cv2
import numpy as np

# load image
img = cv2.imread("leaf.jpg");

# grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY);

# canny
canned = cv2.Canny(gray, 0, 100);

# dilate to close holes in lines
kernel = np.ones((3,3),np.uint8)
mask = cv2.dilate(canned, kernel, iterations = 1);

# find contours
# Opencv 3.4, if using a different major version (4.0 or 2.0), remove the first underscore
_, contours, _ = cv2.findContours(mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE);

# find the biggest contour
biggest_cntr = None;
biggest_area = 0;
for contour in contours:
    area = cv2.contourArea(contour);
    if area > biggest_area:
        biggest_area = area;
        biggest_cntr = contour;

# draw contours
crop_mask = np.zeros_like(mask);
cv2.drawContours(crop_mask, [biggest_cntr], -1, (255), -1);

# opening + median blur to smooth jaggies
crop_mask = cv2.erode(crop_mask, kernel, iterations = 5);
crop_mask = cv2.dilate(crop_mask, kernel, iterations = 5);
crop_mask = cv2.medianBlur(crop_mask, 21);

# crop image
crop = np.zeros_like(img);
crop[crop_mask == 255] = img[crop_mask == 255];

# show
cv2.imshow("leaf", img);
cv2.imshow("gray", gray);
cv2.imshow("canny", canned);
cv2.imshow("mask", crop_mask);
cv2.imshow("cropped", crop);
cv2.waitKey(0);

如果您想将其概括为包括多个前景对象,您可以按大小过滤轮廓并拒绝小于特定阈值的轮廓。