首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将图像裁剪成碎片,然后加入,这能使用OpenCV吗?

将图像裁剪成碎片,然后加入,这能使用OpenCV吗?
EN

Stack Overflow用户
提问于 2013-11-29 03:36:53
回答 2查看 1.2K关注 0票数 3

我有几个样本,从彩色图像,我应该变成二进制。利用自适应阈值,取得了最佳的效果。

数字是非常好的,明确的定义,但周围是嘈杂的,这些“垂直线”分隔每个数字最终被读取为一个数字1的OCR工具,例如。

然后我注意到,在数字周围,图像是干净的。我想,如果我能只剪掉数字(在黑白画之前还是之后)?然后“粘贴”这些数字的白色背景。

我试着使用侵蚀和扩张,但仍然有许多剩余的“点”。如果我能做到我的想法(以上),它将减少侵蚀/扩张,并增加“清洁”的数字在削减之前,我不知道。

这有可能吗?我说得通吗?如果是,我如何使用OpenCV来做到这一点?有什么建议吗?

我正在使用的一些图片:

注:上面的图像并没有经历侵蚀和/或膨胀、自适应阈值的过程。

更新:

@Mahm00d,我试了一下你用第一个图像说的话,得到了下面的图像,这很好,但是前两个数字的反射问题还在继续。有办法解决这个问题吗?我应用了自适应阈值,但图像仍然存在相当大的噪声。

GaussianBlur +带有OTSU标志的Treshold:

GaussianBlur +自适应阈值:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-11-29 08:33:12

通常最好先使用一些去噪技术,比如在进行阈值和形态学之前使用高斯/中值模糊:

(Java代码)

代码语言:javascript
复制
Imgproc.cvtColor(inputMat, gMat, Imgproc.COLOR_RGB2GRAY);
// Gaussian blur : 21x21 window, sigma = 50.0 (select these accordignly)
Imgproc.GaussianBlur(gMat, gMat, new Size(21.0, 21.0), 50.0);
// Otsu thresholding (or any other thresholding techinique...)
Imgproc.threshold(gMat, gMat, 0, 255, Imgproc.THRESH_OTSU | Imgproc.THRESH_BINARY);

你的产出:

以上代码输出:

更新:

这些问题往往需要一些参数值的处理,才能得到一个好的结果,并得到最优的值。对于第二个图像,下面是我使用的代码(自适应阈值)以获得更好的结果:

代码语言:javascript
复制
Imgproc.GaussianBlur(inImg, inImg, new Size(21.0, 21.0), 50.0);
Imgproc.adaptiveThreshold(inImg, inImg, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY, 111, -20);

结果:

当然,这并不完美,但至少反射被移除了。此外,形态过程可以帮助产生更好的结果。

票数 3
EN

Stack Overflow用户

发布于 2013-11-29 08:21:55

一种解决方案是应用膨胀和侵蚀,找出小于X像素的所有轮廓,并用白色填充它们:

代码语言:javascript
复制
int main()
{
    // Load the image as a Grayscale
    Mat image = imread("image.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    // Threshold the image
    image = image > 120;
    // Create bigger image with image width and height + 10 pixels
    Mat image_big = Mat::zeros( image.size().height + 10, image.size().width + 10, CV_8UC1 );
    // Set bigger image to be all white
    image_big.setTo(255);

    Mat image_big_copy;

    // This may vary, you must find it for yourself
    // Dilate image 4 times and erode once
    dilate(image, image, Mat(), Point(-1,-1), 4);
    erode(image, image, Mat(), Point(-1,-1));

    // Copy image in the center of bigger image so you left 5px around image blank/white
    // Create a new ROI that points to center of the bigger image
    Mat image_big_roi = image_big( Rect(Point(5, 5), Size(image.size())) );
    // Copy image to the bigger image ROI
    addWeighted(image_big_roi, 0., image, 1., 0., image_big_roi);

    // Create a data copy of image_big
    image_big.copyTo(image_big_copy);

    // Find all contours in a given image and store them in contours
    vector<vector<Point> > contours;
    findContours(image_big_copy, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

    for( int i = 0; i < contours.size(); i++ )
    {
        // This is your condition to filter out unwanted contours etc.
        // For every contour if its area is bigger/smaller than the sum of pixels
        if ( fabs(contourArea(Mat(contours[i]))) < 800 )
        {
            // Fill a contour with white color
            drawContours(image_big, contours, i, Scalar(255), CV_FILLED);
        }
    }

    imshow("Image original", image);
    imshow("Image edited", image_big);
    waitKey(0);

    return 0;
}

原始图像:

之后:

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

https://stackoverflow.com/questions/20277954

复制
相关文章

相似问题

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