估计白色背景

时间:2016-02-10 16:18:25

标签: opencv image-processing computer-vision interpolation image-segmentation

我的图像有白色不均匀背景(由于光线)。我试图估计背景颜色并将图像转换为具有真白色背景的图像。为此,我根据其亮度估算每个15x15像素块的白色。所以我得到了以下地图(右侧): enter image description here 现在我想插入颜色,以便从15x15块到相邻块更平滑过渡,而且我希望它能消除异常值(左侧的粉红点)。有人可以为此建议好的技术/算法吗? (理想情况下,在OpenCV库中,但不是必需的)

1 个答案:

答案 0 :(得分:3)

从这张图片开始:

enter image description here

您可以在白板上找到具有渐变的图像部分,并应用一点扩张来处理文本的部分。你会得到一个很好的背景与前景分开的面具:

背景:

enter image description here

前景:

enter image description here

然后,您可以使用原始图像上的计算掩码应用inpainting(您需要OpenCV contrib模块photo):

enter image description here

为了证明这与文字颜色无关,我尝试了不同的图像:

enter image description here

导致:

enter image description here

代码:

#include <opencv2/opencv.hpp>
#include <opencv2/photo.hpp>
using namespace cv;

void findText(const Mat3b& src, Mat1b& mask)
{
    // Convert to grayscale
    Mat1b gray;
    cvtColor(src, gray, COLOR_BGR2GRAY);

    // Compute gradient magnitude
    Mat1f dx, dy, mag;
    Sobel(gray, dx, CV_32F, 1, 0);
    Sobel(gray, dy, CV_32F, 0, 1);
    magnitude(dx, dy, mag);

    // Remove low magnitude, keep only text
    mask = mag > 10;

    // Apply a dilation to deal with thick text
    Mat1b K = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
    dilate(mask, mask, K);
}

int main(int argc, const char * argv[])
{
    Mat3b img = imread("path_to_image");

    // Segment white
    Mat1b mask;
    findText(img, mask);

    // Show intermediate images
    Mat3b background = img.clone();
    background.setTo(0, mask);

    Mat3b foreground = img.clone();
    foreground.setTo(0, ~mask);

    // Apply inpainting
    Mat3b inpainted;
    inpaint(img, mask, inpainted, 21, CV_INPAINT_TELEA);

    imshow("Original", img);
    imshow("Foreground", foreground);
    imshow("Background", background);
    imshow("Inpainted", inpainted);
    waitKey();

    return 0;
}