识别嘈杂图像中的拓扑图

时间:2014-04-16 22:53:04

标签: image-processing machine-learning graph-theory topology

我对机器学习或图像处理没有任何经验,所以我希望有人可以就这个问题提出一些初步想法:

下图是番茄植物叶片照片的一个例子。我们有成千上万的这些。我们需要跟踪静脉并输出图形。我们已经让本科生手动追踪了几百个静脉,所以我认为这可以成为机器学习方法的训练集。

enter image description here

所以我的问题:什么类型的过滤器/分类器立即浮现在脑海中?你有什么建议我读或看看吗?

我们首先想到的是,看看定向衍生品。每个像素可以被分类为处于边缘或不处于给定角度的边缘中,并且如果像素处于许多不同角度的像素中,则它可能是斑点而不是静脉。然后可以通过学习调整允许的梯度阈值和角度变化的参数,但这可能不是最佳方式......

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

立即想到两种方法

  1. 滑动窗口神经网络分类器
  2. 识别设置图像中暗/亮像素的阈值(这可以使用机器学习或简单的计算完成),然后进行泛光填充以识别图像中的区域。
  3. 第二种方法应该更简单,更快捷,所以我可能首先将其原型化,看它是否能给出足够好的答案。

    无论如何,我的直觉是解决双重问题会更容易 - 不是试图找到图的边缘和节点,而是找到它的面。从那以后,您可以轻松获得图表。

答案 1 :(得分:2)

我做了这个非常简单的程序来使用opencv过滤静脉区域。我添加了注释来解释操作。保存中间步骤的结果图像。希望它有所帮助。

#include "stdafx.h"

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;

#define INPUT_FILE              "wMTjH3L.png"
#define OUTPUT_FOLDER_PATH      string("")
#define CONTOUR_AREA_THRESHOLD  30.0

int _tmain(int argc, _TCHAR* argv[])
{
    // read image as grayscale
    Mat im = imread(INPUT_FILE, CV_LOAD_IMAGE_GRAYSCALE);
    imwrite(OUTPUT_FOLDER_PATH + string("gray.jpg"), im);
    // smooth the image with a gaussian filter
    Mat blurred;
    GaussianBlur(im, blurred, Size(3, 3), 1.5);
    imwrite(OUTPUT_FOLDER_PATH + string("blurred.jpg"), blurred);
    // flatten lighter regions while retaining the darker vein regions using morphological opening
    Mat morph;
    Mat morphKernel = getStructuringElement(MORPH_ELLIPSE, Size(5, 5));
    morphologyEx(blurred, morph, MORPH_OPEN, morphKernel);
    imwrite(OUTPUT_FOLDER_PATH + string("morph.jpg"), morph);
    // apply adaptive thresholding
    Mat adaptTh;
    adaptiveThreshold(morph, adaptTh, 255.0, ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY_INV, 7, 2.0);
    imwrite(OUTPUT_FOLDER_PATH + string("adaptth.jpg"), adaptTh);
    // morphological closing to merge disjoint regions
    Mat morphBin;
    Mat morphKernelBin = getStructuringElement(MORPH_ELLIPSE, Size(3, 3));
    morphologyEx(adaptTh, morphBin, MORPH_CLOSE, morphKernelBin);
    imwrite(OUTPUT_FOLDER_PATH + string("adptmorph.jpg"), morphBin);
    // find contours
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(morphBin, contours, hierarchy, CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
    // filter contours by region areas and draw
    RNG rng(12345);
    Mat drawing = Mat::zeros(morphBin.size(), CV_8UC3);
    for(int idx = 0; idx >= 0; idx = hierarchy[idx][0])
    {
         if (contourArea(contours[idx]) > CONTOUR_AREA_THRESHOLD)
         {
             Scalar color( rand()&255, rand()&255, rand()&255 );
             drawContours( drawing, contours, idx, color, CV_FILLED, 8, hierarchy );
         }
    }
    imwrite(OUTPUT_FOLDER_PATH + string("cont.jpg"), drawing);
    return 0;
}

对于提供的示例图像,输出如下所示:

enter image description here