我一直在敲打我的头很长一段时间就这一个

我做成像。迄今为止我已经化了我的图像,意味着从一个灰度图像,每一像素在一定的价值都下降了。这给了我唯一些地区出的原始图像具有很多的"零点"的所有围绕这些地区。

接下来我已经运行,长度的编码我的区域为"blob".运行方法的压缩为数据。例如,假设你有化方,你将只有几个运行描述了整个图像。的运行定义的x、y坐标和长度。

当重建的图像,对每个运行,去x、y坐标并加入素在x轴长度的运行。

我现在必须采取行,并创建一个链它将描述的轮廓区域。我不知道如何做到这一点。

我有一大堆的x、y、长度的运行和我有以"浏览"边缘周围的形成 .通常在摄像这个过程是完成与原始图像,但我不能使用的原始图像了这里所以我必须计算它的运行。

我知道这看起来像一个大墙的文本,但我不知道怎么问这种问题更好。

任何的暗示或指针在相同的执行将是真棒。

编辑

谢谢放松,虐待的链接,一些图像:

alt text
(资料来源: tudelft.nl)

在这个例子中,他们处理的图像B入的轮廓C(我叫链)。但是我想产生的轮廓从D,长度

有帮助吗?

解决方案 3

嗯,我丢失的那个合同,但答案是以使用 弗里曼链编码技术

事实上,它是长度编码有什么做的算法,不同于我以前认为的。

其他提示

乍一看我不要看到一个实用的算法。一个穷人的解决方案将是 扩大 原来的图象,从长编码之一。所以如果你是这样的:

A 3B 10A C 8D
C 4D 3A 6C 9A

那里的人物返回的实际素值(例如A=0,B=127,...).你可以写素值成的一个两维阵列(或另一datastructure你的选择)。它看起来像这样:

ABBBAAAAAAAAAACDDDDDDDD
CDDDDAAACCCCCCAAAAAAAAA

之后产生链中,删除该阵和保持链信息。确定这是昂贵的,所以 也许 你可以这样做之前,长度编码的原始图片。

这里有一个非常简单和实用的解决方案,(C++):

#include <iostream>
#include <vector>

struct Run { int x, w; };
enum { EAST, NORTHEAST, NORTH, NORTHWEST, WEST, SOUTHWEST, SOUTH, SOUTHEAST };

int main() {

    const Run data[] = {
        { 7, 2 },
        { 5, 6 },
        { 5, 7 },
        { 5, 7 },
        { 6, 6 },
        { 0, 12 },
        { 0, 12 },
        { 0, 11 },
        { 1, 7 },
        { 3, 4 },
        { 3, 4 },
        { 3, 5 },
        { 3, 7 },
        { 3, 7 },
        { 5, 5 }
    };

    std::vector<Run> runs(data, data + 15);
    std::vector<int> before;
    std::vector<int> after;
    unsigned int i;
    int j;

    for (i = 0; i < runs.size() - 1; ++i) {

        if (runs[i].x < runs[i + 1].x) {

            for (j = 0; j < runs[i + 1].x - runs[i].x - 1; ++j)
                before.push_back(WEST);
            before.push_back(NORTHWEST);

        } else if (runs[i].x > runs[i + 1].x) {

            before.push_back(NORTHEAST);
            for (j = 0; j < runs[i].x - runs[i + 1].x - 1; ++j)
                before.push_back(EAST);

        } else {

            before.push_back(NORTH);

        }

        int first_right(runs[i].x + runs[i].w);
        int second_right(runs[i + 1].x + runs[i + 1].w);

        if (first_right < second_right) {

            after.push_back(SOUTHEAST);
            for (j = 0; j < second_right - first_right - 1; ++j)
                after.push_back(EAST);

        } else if (first_right > second_right) {

            for (j = 0; j < first_right - second_right - 1; ++j)
                after.push_back(WEST);
            after.push_back(SOUTHWEST);

        } else {

            after.push_back(SOUTH);

        }

    }

    for (j = 0; j < runs.back().w - 1; ++j)
        after.push_back(WEST);

    std::reverse(before.begin(), before.end());
    after.insert(after.end(), before.begin(), before.end());

    for (j = 0; j < int(after.size()); ++j) {
        switch (after[j]) {
        case EAST:      std::cout << "EAST\n";      break;
        case NORTHEAST: std::cout << "NORTHEAST\n"; break;
        case NORTH:     std::cout << "NORTH\n";     break;
        case NORTHWEST: std::cout << "NORTHWEST\n"; break;
        case WEST:      std::cout << "WEST\n";      break;
        case SOUTHWEST: std::cout << "SOUTHWEST\n"; break;
        case SOUTH:     std::cout << "SOUTH\n";     break;
        case SOUTHEAST: std::cout << "SOUTHEAST\n"; break;
        }
    }

}

这一工作通过循环的运行、测试左右端点为方向他们跳跃到,并添加适当数量的链元到两个向量:一个在前进了,右侧,一个相反的顺序,对于左侧。然后,它将连接两个链通过添加适当的链接数量为最后的扫描线,然后转左侧链和追加它的正确产生的最终链。

希望这个是你在找什么!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top