سؤال

لقد كنت ضجيج رأسي لفترة طويلة على هذا واحد

أنا أقوم بالتصوير. لقد عدت حتى الآن صوري، مما يعني أنه من صورة رمادية، يتم إسقاط كل بكسل تحت قيمة معينة. هذا يعطيني بعض المناطق فقط من الصورة الأصلية مع الكثير من "صفر بكسل" في جميع أنحاء تلك المناطق.

بعد ذلك، قمت بتشغيل الطول ترميز منطقتي إلى "Blobs". يعمل هي طريقة ضغط البيانات. على سبيل المثال، لنفترض أن لديك ميدان، فستكون لديك سوى عدد قليل من أشواط وصف الصورة بأكملها. يتم تعريف التشغيل بواسطة x، y الإحداثيات وطولها.

عند إعادة إنشاء الصورة، لكل تشغيل، انتقل إلى x و y forens وإضافة وحدات البكسل على المحور X لطول التشغيل.

الآن لا بد لي من أخذ أشواط وإنشاء سلسلة من ذلك سوف تصف محيط المنطقة. أنا لا أعرف كيف أفعل ذلك.

لدي مجموعة من X، Y، الطول يعمل، وعلي "التنقل" حول الحواف لتشكيل سلسلة. وبعد عادة في تصوير هذه العملية تتم مع الصورة الأصلية ولكن لا يمكنني استخدام الصورة الأصلية بعد الآن حتى يتعين علي حسابها مع التشغيل.

أعلم أن هذا يبدو وكأنه جدار نص كبير لكنني لا أعرف كيف أسأل هذا السؤال بشكل أفضل.

سيكون أي تلميحات أو مؤشرات على التنفيذ مماثل رهيبة.

تعديل

بفضل الاسترخاء، رابط مريض بعض الصور:

alt text
(مصدر: tudelft.nl.)

في هذا المثال، يقومون بمعالجة الصورة B في Contour C (التي أسمي السلسلة). ومع ذلك، أود إنشاء Contour من D، أطوال المدى

هل كانت مفيدة؟

المحلول 3

حسنا لقد فقدت هذا العقد ولكن الجواب هو استخدام سلسلة ترميز سلسلة فريمان

حقيقة أنه يتم تشغيل أطوال ترميز لا علاقة له بالجوارد، على عكس الفكر في السابق.

نصائح أخرى

للوهلة الأولى لا أرى خوارزمية عملية لذلك. سيكون حل الرجل الفقير وسعت الصورة الأصلية من الطول المشفرة واحدة. لذلك إذا كانت خطوطك تبدو وكأنها هذه:

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

حيث ترجع الشخصيات قيمة البكسل الفعلية (مثل A = 0، B = 127، ...). يمكنك كتابة قيم البكسل في صفيف ثنائي الأبعاد (أو دراس بيانات آخر من اختيارك). يبدو أن هذا:

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;
        }
    }

}

يعمل هذا بالتأكيد عن طريق التكرار عبر المدى، واختبار نقاط النهاية اليسرى واليمنى للاتجاه، وإضافة العدد المناسب لعناصر السلسلة إلى متجهتين: واحد من أجل الأمام، والجانب الأيمن، والآخر في ترتيب عكسي ، على اليسار. ثم يربط السلاسلتين عن طريق إضافة العدد المناسب من الروابط للحصول على آخر Scanline، ثم يعكس السلسلة الجانبية اليسرى ويشملها إلى اليمين لإنتاج السلسلة النهائية.

آمل أن يكون هذا ما تبحث عنه!

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top