Re[5]: профи или упоротый
От: __kot2  
Дата: 19.02.15 03:13
Оценка: +6 :))) :))) :))) :)))
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>можно и функцию но тогда будет множество мелких функций, тут как я вижу одна функция не требующая её дробить еще на несколько функций
одна фукнция делает одну вещь
здесь есть
— инициализация
— перебор
— вычисление условия в переборе
— маркировка обнаруженной фигни
— выбор рандомной точки

это все отдельные ф-ии должны быть по уму

пока что уровень этого кода — "старательный школьник"
если сюда еще добавить goto, то будет "старательный школьник-наркоман"
Re: профи или упоротый
От: VladFein США  
Дата: 19.02.15 20:59
Оценка: 12 (3) +5
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал

J>тыц

А кроме вчетверо вложенного if(found) { break; } Вас ничего не смущает?
"Профессиональное" отрицание всякого рода венгерских нотаций, например? Находясь в самом вложенном цикле, как определить что перемменная xa локальная, а xout — член класса (или глобальная переменная)?
Analyse — это глагол, а не вопрос. Он не должен быть bool. Функция возвращает true если на картинке найдена цифра; может, назвать её HasDigit? Кроме того, вызывающую сторону не интересует — какая цифра была найдена? Раз мы-то знаем, может возвращать эту цифру, на всякий случай? Или -1 если не нашли?
После вызова этой функции, будет продолжен поиск следующей цифры? Начиная, опять, с преобразования в монохромный image?
В самом первом if(found) { break; }, мы знаем что цифра найдена, и имеем ВСЮ информацию для "Mark detected digit". Если сделать это сразу — переменные nr, deg и xout/yout можно не выводить за пределы цикла. Кроме того, функцию можно будет не прерывать, а продолжать искать следующие цифры прямо с этого места!
Функция Analyse (или HasDigit) должна бы быть const. Что это за разрушительный анализ?
Однобитный битмэп не обязательно держать в 24-битном. Я бы сделал bool monoImage[][], заодно повысил бы шансы поместиться в кэш. Это, кстати, упростит корявое условие if(!image->pixels[ya][xa][0] == 0x00). Вы в самом деле хотели сперва сделать bitwise NOT этому байту и потом сравнить с 0x00?
А это что делает: Select random point of digit? Забавный side effect? Он хотя бы документирован?
Меня также смущает число 160. Во-первых, почему 160? А во-вторых, почему одинаковое число для всех трёх цветов? Учитывая, что gray = 0.299R+0.587G+0.114B...
Re: профи или упоротый
От: __kot2  
Дата: 19.02.15 03:08
Оценка: +7
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>goto? не, не слышал
да какое там нафиг goto? там return должен быть из ф-ии
то же мне, нашли применение goto
профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 01:56
Оценка: +1 -4 :)
goto? не, не слышал

bool AntiCaptcha::Analyse()
{
    // Differentiate between background and foreground
    for(unsigned int y = 0; y < height; ++y)
    {
        for(unsigned int x = 0; x < width; ++x)
        {
            if(image->pixels[y][x][0] >= 160 && image->pixels[y][x][1] >= 160
                    && image->pixels[y][x][2] >= 160)
            {
                image->pixels[y][x][0] = 0xFF;
                image->pixels[y][x][1] = 0xFF;
                image->pixels[y][x][2] = 0xFF;
            }
            else
            {
                image->pixels[y][x][0] = 0x00;
                image->pixels[y][x][1] = 0x00;
                image->pixels[y][x][2] = 0x00;
            }
        }
    }

    // Compare vectors with image
    unsigned int xa, ya;

    bool found = true;
    int nr = -1;
    int deg = 0;

    for(int digit = 0; digit < numDigits; ++digit)
    {
        for(unsigned int y = 0; y < height; ++y)
        {
            for(unsigned int x = 0; x < width; ++x)
            {

                for(deg = 0; deg < 11; ++deg)
                {
                    xa = x;
                    xout = x;
                    ya = y;
                    yout = y;

                    found = true;

                    for(int i = 0; i < lenDigits[digit]; ++i)
                    {
                        xa += transformed[digit][deg][i].first;
                        ya += transformed[digit][deg][i].second;

                        if(xa < 0 || xa >= width || ya < 0 || ya >= height)
                        {
                            found = false;
                            break;
                        }

                        if(!image->pixels[ya][xa][0] == 0x00)
                        {
                            found = false;
                            break;
                        }
                    }

                    if(found)
                    {
                        break;
                    }

                }

                if(found)
                {
                    break;
                }
            }

            if(found)
            {
                break;
            }
        }

        if(found)
        {
            nr = digit;
            break;
        }
    }

    // Mark detected digit
    if(nr != -1)
    {
        xa = xout;
        ya = yout;

        for(int i = 0; i < lenDigits[nr]; ++i)
        {
            xa += transformed[nr][deg][i].first;
            ya += transformed[nr][deg][i].second;

            image->pixels[ya][xa][0] = 0xFF;

        }
    }

    if(nr == -1)
    {
        return false;
    }

    // Select random point of digit
    int vec = random(0,lenDigits[nr]);
    for(int i=0; i < vec; ++i)
    {
        xout += transformed[nr][deg][i].first;
        yout += transformed[nr][deg][i].second;
    }

    return true;
}


тыц
Отредактировано 19.02.2015 2:22 jyuyjiyuijyu . Предыдущая версия .
Re[3]: профи или упоротый
От: watchmaker  
Дата: 19.02.15 02:41
Оценка: +6
Здравствуйте, jyuyjiyuijyu, Вы писали:

J> гото там то что доктор прописал


Функцию там надо, а не goto. Вот прямо как в коде комментарии написаны, так в этих местах на функции и разбивать. И останется в функции CompareVectors один return из внутреннего цикла без всяких goto или break.
Re[5]: профи или упоротый
От: pestis  
Дата: 20.02.15 14:10
Оценка: -2 :))) :)
Здравствуйте, Kernan, Вы писали:

K>Ничего не надо писать на С. Везде можно использовать С++ и по производительности он будет как С-шный код если ты умеешь писать на С++.


Чтобы крестовый код только догнал по производительность хорошо написанный чисты С придется отказаться от шаблонов, исключений, классов и еще кучи всего. Ну и смысла тогда морочиться с крестами если сишный код получается гораздо чище и намного легче читается?
Re[3]: профи или упоротый
От: pestis  
Дата: 20.02.15 06:45
Оценка: -5
Здравствуйте, velkin, Вы писали:


V>Ну или разработчики OpenCV как вариант.


Это низкоуровневая обработка изображений. Ее вообще нужно писать на чистом С хорошим оптимизирующим компилятором. Просто разработчики OpenCV в основной массе школьники, копипастящие алгоритмы из учебников.
Re[9]: профи или упоротый
От: Evgeny.Panasyuk Россия  
Дата: 20.02.15 22:32
Оценка: 11 (3) +1
Здравствуйте, velkin, Вы писали:

EP>>Это где же жёсткая кодогенерация у Страуструпа? Его книжки как раз подходят новичкам.

V>А вот и зря, ещё в 1999 году его купил, Язык программирования С++ 3-е издание. Его можно рассматривать как отличный справочник, но не как учебное пособие. Моё мнение, человек начитавшись Страуструпа освоит языковые конструкции, голый синтаксис, но третья часть "Стандартная библиотека" не даст понимания глубинного смысла всего этого действа.

Нет, это не справочник. Там большая часть это именно обучение хорошему стилю.
Вот взять например главу про парсер/калькулятор — там сначала строится один вариант, показываются недостатки, потом через ввод дополнительных средств показывается следующий вариант, и эмнип так несколько раз. Это разве справочник? А вот его C++ ARM — это как раз справочник.
Да и вообще, у Страуструпа TC++PL это не единственная книга. TC++PL это скорее средний уровень нежели начальный.
Для совсем начинающих у него есть "Programming — Principles and Practice Using C++", причём это не просто для начинающих C++, а для начинающих программировать вообще.

EP>>А Майерс это вообще что-то типа common pitfalls, а не учебник.

V>...
V>Проблема в том, что все его материалы даны в виде советов, даже про STL. Сначала мне думается нужно научиться использовать STL и понять его смысл, а уже потом изучать советы как дополнение.

Мой комментарий был про то, что у Майерса не шаблонное метапроргаммирование и кодогенерация, а всего лишь набор советов.
С тем что начинать изучение STL нужно не с советов — полностью согласен.

V>Мне просто непонятно, почему хают кодогенерацию называя её медленной, вот и размышляю. По всем прикидкам скорость исполнения программ такая же как в Си, но выражения гораздо более лаконичные и вкладываются друг в друга.


Это известный и крайне популярный миф, мол если нужна скорость — то нужно переписать на C. На практике же получается что код на C медленней. Страуструп, кстати, постоянно борется с этим мифом — раскрывает тему в своих статьях, презентациях.

Почему программисты так охотно в верят в этот миф? Думаю эта вера основывается на следующей эвристике: "Чем больше абстракций — тем медленней код. Чтобы получить быстрый код — нужно принести абстракции в жертву богу Performance, щедро полив его алтарь boilerplate'ом и lines of code'ом, сгорбившись над клавиатурой выстрачивая C код" Причём для многих языков эта эвристика действительна справедлива.
Проверить, убедится, осознать что в C++ получилась вишенка — крайне дешёвые и зачастую бесплатные абстракции — видимо не позволяет невежество.

http://www.stepanovpapers.com/BYTE_com.htm
Alexander Stepanov:
What do I mean when I say that an algorithm does not "impose any performance penalty"? In other words, how do you know that a generic algorithm is efficient? An algorithm is called relatively efficient if it's as efficient as a nongeneric version written in the same language, and it's called absolutely efficient if it's as efficient as a nongeneric assembly language version.

For many years, I tried to achieve relative efficiency in more advanced languages (e.g., Ada and Scheme) but failed. My generic versions of even simple algorithms were not able to compete with built-in primitives. But in C++ I was finally able to not only accomplish relative efficiency but come very close to the more ambitious goal of absolute efficiency. To verify this, I spent countless hours looking at the assembly code generated by different compilers on different architectures.

Re[7]: профи или упоротый
От: watchmaker  
Дата: 19.02.15 03:23
Оценка: 2 (1) +2
Здравствуйте, jyuyjiyuijyu, Вы писали:



J>здесь одно логическое действие на определенном уровне абстракции

Вся программа — это тоже одно действие на своём уровне абстракции. Но это не означает, что всё программу нужно в единственную функцию main() впихнуть.
Тут же само действие слишком сложно, а функция слишком длинна. Разбивать её, конечно, надо. А на "логичность действия" это отрицательно не повлияет.

J>ты реально так сам пишешь?

Стараемся так писать.
Re[2]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 02:32
Оценка: +1 -2
Здравствуйте, MaxRos, Вы писали:

MR>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>goto? не, не слышал


MR>а нафига там goto, если у каждого цикла уже есть выражение для остановки, куда этот found и можно засунуть


уже лучше но всё равно костыль, гото там то что доктор прописал
Re: профи или упоротый
От: pestis  
Дата: 19.02.15 06:04
Оценка: -3
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал


Упоротый. Но гото тут не при чем. Только упопротый станет писать высокоуровневую обработку изображений на крестах. Ну или школьник, как вариант.
Re[8]: профи или упоротый
От: __kot2  
Дата: 20.02.15 21:37
Оценка: +1 :))
Здравствуйте, Evgeny.Panasyuk, Вы писали:
EP>Это где же жёсткая кодогенерация у Страуструпа? Его книжки как раз подходят новичкам. А Майерс это вообще что-то типа common pitfalls, а не учебник.
Страуструп может представлять только исторический интерес. Глядя на его код просто умиляешься, как будто "Повесть о полку Игореве" читаешь.
Нет, от чтения, конечно, хуже не будет, но не надо воспринимать его буквально.
Из дурацких книг по С++ отдельно могу отметить "решение несуществующих задач" Саттера.
Re[7]: профи или упоротый
От: pestis  
Дата: 24.02.15 16:10
Оценка: +1 -1 :)
Здравствуйте, velkin, Вы писали:

V>Использовать или не использовать исключения право каждого программиста, возразить нечего по поводу того, что они замедлят работу по сравнению с тем кодом, который написан без исключений. Но что касается шаблонов С++ абсолютно не согласен. Мы же не об ООП говорим, как в случае тех же исключений. Шаблоны С++ это просто генератор кода. Как по вашему он замедляет работу?


Очевидно, генерирует неоптимальный код.

V>Внутри всё оптимизировано, хотите используйте динамический массив vector, если нужен статический, то пожалуйста array. Итераторы для разных видов контейнеров, тех же последовательных или ассоциативных, оптимизированы по максиму. Важно научиться различать используемые операторы, и тогда скорость алгоритмов не уступят Си ни на такт. Потому что внутри генерируется доступ по тем же указателям, просто есть возможность не парить себе мозги и доверить реализацию оптимального способа в каждом конкретном случае разработчикам STL. Ну и собственные алгоритмы и библиотеки алгоритмов станут иными.


Откуда разработчикам STL знать как нужно оптимизировать код для МОЕЙ задачи? Да и практический опыт говорит в мою пользу: если выкинуть стандартную коллекцию и написать свою, глубоко заточенную на конкретную задачу, то производительность вырастает в несколько раз.

V>А по поводу легче читается или нет тоже большой вопрос. Я могу только сказать, что кодогенерации научиться сложнее, так как это следующий уровень абстракций, а значит и следующий уровень программиста. На мой взгляд программисты использующие шаблоны С++ стоят по уровню умений выше чистых сишников, так как первым в случае необходимости опустится ниже легче, чем вторым поднятся. Хотя процесс этот неоднозначен. Как-то помог студенту решить завершающую курс задачу на Борланде С++ 3.1, весь исплевался. Здесь очевидно так же.


Очевидно что код на С делает ровно то что написано, ровно так как написано. Поэтому его легко писать, легко читать и легко оптимизировать. Если нужны абстракции более высокого уровня, совершенно необязательно пытаться выразить их на C. Существуют такие прекрасные языки, как Python, OCaml, Haskel, Java, Scala, которые легко и прозрачно интегрируются с С сохраняя его производительность и чистоту кода. В такой архитектуре написан numpy который сочетает изумительную производительность С и уникальную скорость кодирования python.
Re[5]: профи или упоротый
От: watchmaker  
Дата: 19.02.15 03:14
Оценка: +2
Здравствуйте, jyuyjiyuijyu, Вы писали:


J>тут как я вижу одна функция не требующая её дробить еще на несколько функций

Да ты упоротый не профи
Именно такие функции дробить и надо.
Re[5]: профи или упоротый
От: __kot2  
Дата: 20.02.15 03:22
Оценка: +1 -1
Здравствуйте, velkin, Вы писали:
V>А по мне так OpenCV прекрасно работает, и даже с CUDA нет никаких проблем.
я не в курсе как он работет, если честно.
у со своей колокольни кому сказать что куча научного софта на самом деле гавно, которое прдюсит невалидный кал огромных обьемов, загрязнящий что то осмысленное. кал этот совершенно бесполезно испавлять. только его аффтар понимает в этих макаронах хоть что-то. это называется job security, да, когда только тпкущие разработчики могут что-то там сделать, а остальные потеряются где-то пытаясь понять что имелось в виду во всей вот этой вот бадяге.
Re[7]: профи или упоротый
От: Evgeny.Panasyuk Россия  
Дата: 20.02.15 17:48
Оценка: +2
Здравствуйте, velkin, Вы писали:

V>Использовать или не использовать исключения право каждого программиста, возразить нечего по поводу того, что они замедлят работу по сравнению с тем кодом, который написан без исключений.


zero-cost exceptions на happy-path могут быть даже быстрее чем раскиданные по всему коду if(errorX) goto ERROR_X;

V>Важно научиться различать используемые операторы, и тогда скорость алгоритмов не уступят Си ни на такт.


Конечно можно выписывать на C каждый вариант вручную (либо генерировать) чтобы получить код не медленнее чем на C++ — но по факту уходят в медленный runtime полиморфизм — например, или взять тот же qsort — отсюда и тормоза.

V>И ещё есть множество книг по шаблонам C++, и я вполне понимаю, почему сишники их не читают. Особенно, когда знакомство начинается с Александреску, а это всё, туши свет. Потому я бы крайне рекомендовал прочесть книгу STL для программистов на C++ — Леен Аммерааль, а не всяких Страуструпов, Мейерсов, Вандевурдов с Джосаттисами и прочих весёлых ребят. А иначе новичку трудно понять трансформацию кода из Си в С++ и почему последнее в итоге лучше. Вместо этого сразу начинается жёсткая кодогенерация, у сишника рвотный рефлекс, и далее мы имеем множество людей хающих шаблоны С++, но не имеющих о них реального представления.


Это где же жёсткая кодогенерация у Страуструпа? Его книжки как раз подходят новичкам. А Майерс это вообще что-то типа common pitfalls, а не учебник.
Re[4]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 02:49
Оценка: -1
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>> гото там то что доктор прописал


W>Функцию там надо, а не goto. Вот прямо как в коде комментарии написаны, так в этих местах на функции и разбивать. И останется в функции CompareVectors один return из внутреннего цикла без всяких goto или break.


можно и функцию но тогда будет множество мелких функций, тут как я вижу одна функция не требующая её дробить еще на несколько функций
Re[6]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:17
Оценка: :)
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>можно и функцию но тогда будет множество мелких функций, тут как я вижу одна функция не требующая её дробить еще на несколько функций
__>одна фукнция делает одну вещь
__>здесь есть
__>- инициализация
__>- перебор
__>- вычисление условия в переборе
__>- маркировка обнаруженной фигни
__>- выбор рандомной точки

__>это все отдельные ф-ии должны быть по уму


друг это перебор, ты реально так сам пишешь? здесь одно логическое действие на определенном уровне абстракции
Re[7]: профи или упоротый
От: __kot2  
Дата: 19.02.15 03:24
Оценка: +1
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>друг это перебор, ты реально так сам пишешь? здесь одно логическое действие на определенном уровне абстракции
вот представь себе что я автомеханик
ко мне заходят два школьника на Москвиче и один ржет на другим — мы потеряли гайки от колес и мы колеса пластелином прилепили. а надо-то было клеем! представляете какой мой друг тупой.

это такая фантастическая тупость, что я даже не знаю, что возразить. если тебе кажется, что это нормальный код — да пиши на здоровье
Re: профи или упоротый
От: andy1618 Россия  
Дата: 19.02.15 04:33
Оценка: +1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал


Похоже, что как раз "слышал"
.. ибо с goto ситуация интересная:
1) Начинающий программист пишет код с goto по незнанию.
2) Продолжающий программист в курсе, что goto — моветон, и старается избежать
его любыми способами. Что мы и наблюдаем в данном случае.
3) Профессионал тоже избегает goto, только способы уже не "любые", а "изящные"

Резюме:
Ни goto, ни break тут не нужны — нужна отдельная функция с return. Заодно и читабельность кода улучшится.
Ещё резануло глаз присутствие магических чисел (160, 11) — обычно это тоже признак п.1
goto
Re[2]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 05:31
Оценка: :)
Здравствуйте, andy1618, Вы писали:

A>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>goto? не, не слышал


A>Похоже, что как раз "слышал"

A>.. ибо с goto ситуация интересная:
A>1) Начинающий программист пишет код с goto по незнанию.
A>2) Продолжающий программист в курсе, что goto — моветон, и старается избежать
A>его любыми способами. Что мы и наблюдаем в данном случае.
A>3) Профессионал тоже избегает goto, только способы уже не "любые", а "изящные"

насчет профи очень спорно, гото очень много в ядре систем написанных на С
Re[2]: профи или упоротый
От: RiNSpy  
Дата: 19.02.15 09:38
Оценка: +1
Здравствуйте, andy1618, Вы писали:

A>Резюме:

A>Ни goto, ни break тут не нужны — нужна отдельная функция с return. Заодно и читабельность кода улучшится.
A>Ещё резануло глаз присутствие магических чисел (160, 11) — обычно это тоже признак п.1

По объективным параметрам код, конечно, плохой, но — нужно учитывать, для чего и в какой ситуации этот код писался:

если цель была написать код быстро, код будет использоваться один раз и не будет расти, им не будет больше никто пользоваться, то нормальный код. Например, при разбиении на функции, в данном случае читабельность кода может и упасть, просто потому что функции по порядку читать труднее, придётся прыгать из основного метода в вызываемые функции, чтобы понять, что там происходит.

Условия выхода из циклов тоже вполне читабельны.
Re: профи или упоротый
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 19.02.15 12:53
Оценка: +1
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал

Тут наверное "Абстракции? Нет, не слышал."
Sic luceat lux!
Re[4]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 02:15
Оценка: +1
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, velkin, Вы писали:

V>>Ну или разработчики OpenCV как вариант.
__>ну ни для кого тут сокретом не являются, думаю, что многий продакшен код такие вот макароны написанные левой ногой.
__>просто большинство обычных людей это касается только когда в таком стиле пишут OpenSSL и потом удивлются, что там глк на глюке. а так то такой это только проблема товарищей из opencv как они этот код будут расширять, отлаживать или портировать. да и если весь opencv таквоц то судя по всему opencv работает только из-за компенсации багов друг другом и только ра малине девелоперов и только на их примерах

А по мне так OpenCV прекрасно работает, и даже с CUDA нет никаких проблем. Особенность OpenCV в малой связности, а это значит изменение одного не влечёт багов другого. Вот разобъёте вы проект на несколько функций, но они используются ровно один раз, дальше что? Замечу речь не идет об объектно-ориентированных приложениях, вот эти самые функции могут выступать в них всего лишь кирпичиками. В линуксе, когда работаешь с оборудованием всякие лишние деления заканчиваются не просто плохо, а ужасно. Назовите историю успеха мне интересно будет послушать.

Так то я на Qt в последние 7 лет подсел, так что не стал бы обхаивать за зря предложенную идеологию всяких энтерпрайзов, а даже напротив. Но увы, почему-то то, что прекрасно пашет в одних решениях, в других терпит полное фиаско. Впрочем Qt тоже не особо всё делит, можно поделить гораздо больше. Хорошо делят и абстрагируют в Java, но она тормоз, причём может быть именно поэтому и тормоз. Излишнее деление не всегда проявляется сразу, пока оно не дойдёт до маниакального состояния.

Иными словами в прошлом я бы тоже всё поделил на такой задаче, и поделил, но наступил облом. Практика Qt, а до этого .NET и так далее не помогли, а лишь мешали. Хотя, когда лепишь точно так же какое-нибудь гуишное приложение, всё работает на ура. И использование return срабатывает просто отлично. В общем мой вывод, что сишники тоже кое в чём правы. Вот тогда мир разделился ещё на две части, один это динамическая архитектура, второй молотилка битов. Она может быть как процедурной, так и в обобщённой парадигме. И молотилки имеют свою специфику, их нельзя судить с позиции ООП.
Re[6]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 17:07
Оценка: +1
Здравствуйте, pestis, Вы писали:

P>Чтобы крестовый код только догнал по производительность хорошо написанный чисты С придется отказаться от шаблонов, исключений, классов и еще кучи всего. Ну и смысла тогда морочиться с крестами если сишный код получается гораздо чище и намного легче читается?


Использовать или не использовать исключения право каждого программиста, возразить нечего по поводу того, что они замедлят работу по сравнению с тем кодом, который написан без исключений. Но что касается шаблонов С++ абсолютно не согласен. Мы же не об ООП говорим, как в случае тех же исключений. Шаблоны С++ это просто генератор кода. Как по вашему он замедляет работу?

Внутри всё оптимизировано, хотите используйте динамический массив vector, если нужен статический, то пожалуйста array. Итераторы для разных видов контейнеров, тех же последовательных или ассоциативных, оптимизированы по максиму. Важно научиться различать используемые операторы, и тогда скорость алгоритмов не уступят Си ни на такт. Потому что внутри генерируется доступ по тем же указателям, просто есть возможность не парить себе мозги и доверить реализацию оптимального способа в каждом конкретном случае разработчикам STL. Ну и собственные алгоритмы и библиотеки алгоритмов станут иными.

А по поводу легче читается или нет тоже большой вопрос. Я могу только сказать, что кодогенерации научиться сложнее, так как это следующий уровень абстракций, а значит и следующий уровень программиста. На мой взгляд программисты использующие шаблоны С++ стоят по уровню умений выше чистых сишников, так как первым в случае необходимости опустится ниже легче, чем вторым поднятся. Хотя процесс этот неоднозначен. Как-то помог студенту решить завершающую курс задачу на Борланде С++ 3.1, весь исплевался. Здесь очевидно так же.

И ещё есть множество книг по шаблонам C++, и я вполне понимаю, почему сишники их не читают. Особенно, когда знакомство начинается с Александреску, а это всё, туши свет. Потому я бы крайне рекомендовал прочесть книгу STL для программистов на C++ — Леен Аммерааль, а не всяких Страуструпов, Мейерсов, Вандевурдов с Джосаттисами и прочих весёлых ребят. А иначе новичку трудно понять трансформацию кода из Си в С++ и почему последнее в итоге лучше. Вместо этого сразу начинается жёсткая кодогенерация, у сишника рвотный рефлекс, и далее мы имеем множество людей хающих шаблоны С++, но не имеющих о них реального представления.
Re[3]: профи или упоротый
От: Lepsik Индия figvam.ca
Дата: 23.02.15 18:57
Оценка: +1
---один раз сойдет (как уже писали), но меня смущает прекрасное оформление этого кода. То ли корпоративные стандарты оформления свято блюдутся даже для одно-минутных поделок, то ли код был написан

Этот код ужасен с корпоративной точки зрения.
Re: профи или упоротый
От: MaxRos  
Дата: 19.02.15 02:26
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал


а нафига там goto, если у каждого цикла уже есть выражение для остановки, куда этот found и можно засунуть
Re[2]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:13
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>goto? не, не слышал
__>да какое там нафиг goto? там return должен быть из ф-ии
__>то же мне, нашли применение goto

ну можно и ретурн но в основном когда так делают (как у автора) то должен еще какой то код выполнятся ниже циклов
Отредактировано 19.02.2015 3:14 jyuyjiyuijyu . Предыдущая версия .
Re[6]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:19
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, jyuyjiyuijyu, Вы писали:



J>>тут как я вижу одна функция не требующая её дробить еще на несколько функций

W>Да ты упоротый не профи
W>Именно такие функции дробить и надо.

сам упоротый

со мной даже автор кода согласен что это одна функция )))
Re[8]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:30
Оценка:
Здравствуйте, watchmaker, Вы писали:

W>Здравствуйте, jyuyjiyuijyu, Вы писали:




J>>здесь одно логическое действие на определенном уровне абстракции

W>Вся программа — это тоже одно действие на своём уровне абстракции. Но это не означает, что всё программу нужно в единственную функцию main() впихнуть.
W>Тут же само действие слишком сложно, а функция слишком длинна. Разбивать её, конечно, надо. А на "логичность действия" это отрицательно не повлияет.

J>>ты реально так сам пишешь?

W>Стараемся так писать.

ну естественно я имел ввиду уровень абстракции соответствующий разбиению на функции

а функция тут длинна из за авторского ноу-хау с обходом гото)))
Re[8]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:33
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>друг это перебор, ты реально так сам пишешь? здесь одно логическое действие на определенном уровне абстракции
__>вот представь себе что я автомеханик
__>ко мне заходят два школьника на Москвиче и один ржет на другим — мы потеряли гайки от колес и мы колеса пластелином прилепили. а надо-то было клеем! представляете какой мой друг тупой.

__>это такая фантастическая тупость, что я даже не знаю, что возразить. если тебе кажется, что это нормальный код — да пиши на здоровье


неубедительно, пацаны могут под фуру залететь а мой код будет работать не хужее твоего и возможно даже проще пониматься
Re[9]: профи или упоротый
От: __kot2  
Дата: 19.02.15 03:40
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>неубедительно, пацаны могут под фуру залететь а мой код будет работать не хужее твоего и возможно даже проще пониматься
возможно этот код взкрывает сервер Пентагона

но если говорить не гипоттетически, а на пальцах.
вот есть, например Жигули 6ка и Bmw 6ка. Вот этот код — Жигули 6ка. Нормальные люди на таком гавне не ездят. Они даже не подойдут к нему. И если вдруг такое достанется, то просто выкинут на помойку, а не будут разбираться, что оно там, прет ничуть не хуже BMW и возможно даже надежнее или жрет меньше. Даже свое время тратить не будут на проверку этих вещей.
Re[10]: профи или упоротый
От: jyuyjiyuijyu  
Дата: 19.02.15 03:53
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>неубедительно, пацаны могут под фуру залететь а мой код будет работать не хужее твоего и возможно даже проще пониматься
__>возможно этот код взкрывает сервер Пентагона

__>но если говорить не гипоттетически, а на пальцах.

__>вот есть, например Жигули 6ка и Bmw 6ка. Вот этот код — Жигули 6ка. Нормальные люди на таком гавне не ездят. Они даже не подойдут к нему. И если вдруг такое достанется, то просто выкинут на помойку, а не будут разбираться, что оно там, прет ничуть не хуже BMW и возможно даже надежнее или жрет меньше. Даже свое время тратить не будут на проверку этих вещей.

примеры всё убедительнее и убедительнее

незнаю как у вас на рублёвке а у нас и жигули в почёте и даже на запорожцах ездят )))
Re[11]: профи или упоротый
От: __kot2  
Дата: 19.02.15 04:15
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:
J>примеры всё убедительнее и убедительнее

J>незнаю как у вас на рублёвке а у нас и жигули в почёте и даже на запорожцах ездят )))

вот и я говорю — если всё и так устраивает, то на здоровье
Re: ленивый
От: bazis1 Канада  
Дата: 19.02.15 04:18
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал

поленился, по ходу, выделить кусок фукции и сделать refactor->extract function.

J>
J>bool AntiCaptcha::Analyse()
J>

а, все ясно, школота
Re[3]: профи или упоротый
От: andy1618 Россия  
Дата: 19.02.15 09:13
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>>>goto? не, не слышал


A>>Похоже, что как раз "слышал"

A>>.. ибо с goto ситуация интересная:
A>>1) Начинающий программист пишет код с goto по незнанию.
A>>2) Продолжающий программист в курсе, что goto — моветон, и старается избежать
A>>его любыми способами. Что мы и наблюдаем в данном случае.
A>>3) Профессионал тоже избегает goto, только способы уже не "любые", а "изящные"

J>насчет профи очень спорно, гото очень много в ядре систем написанных на С



Да, мне тоже иногда приходится этот оператор использовать,
например, когда пишу что-нибудь для души на VBA для Excel — там для обработки
ошибок есть конструкция On Error GoTo <label>, альтернативы которой нет.
Re[10]: профи или упоротый
От: dr. Acula Украина  
Дата: 19.02.15 18:51
Оценка:
__>Нормальные люди ... И если вдруг такое достанется, то просто выкинут на помойку, а не будут разбираться, ... Даже свое время тратить не будут на проверку этих вещей.

да, подход типичного "школоло", который "знает как надо делать, а остальные — дебилы".
Re[11]: профи или упоротый
От: __kot2  
Дата: 19.02.15 19:56
Оценка:
Здравствуйте, dr. Acula, Вы писали:
DA>да, подход типичного "школоло", который "знает как надо делать, а остальные — дебилы".
да нет, просто чем старше становишься, тем больше свое время ценить начинаешь
Re[2]: профи или упоротый
От: johny5 Новая Зеландия
Дата: 20.02.15 00:24
Оценка:
Здравствуйте, andy1618, Вы писали:

A>Здравствуйте, jyuyjiyuijyu, Вы писали:


J>>goto? не, не слышал


A>Похоже, что как раз "слышал"

A>.. ибо с goto ситуация интересная:
A>1) Начинающий программист пишет код с goto по незнанию.
A>2) Продолжающий программист в курсе, что goto — моветон, и старается избежать
A>его любыми способами. Что мы и наблюдаем в данном случае.
A>3) Профессионал тоже избегает goto, только способы уже не "любые", а "изящные"

У меня сложилось другое видение.
Начинающий и продолжающий программист никогда не напишет goto, потому что это запрещается.
Профессионал прищуривается.
Re[2]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 00:47
Оценка:
Здравствуйте, pestis, Вы писали:

P>Упоротый. Но гото тут не при чем. Только упопротый станет писать высокоуровневую обработку изображений на крестах. Ну или школьник, как вариант.


Ну или разработчики OpenCV как вариант.

/****************************************************************************************\
*                     Multi-Scale variant of Classical Hough Transform                   *
\****************************************************************************************/

//DECLARE_AND_IMPLEMENT_LIST( _index, h_ );
IMPLEMENT_LIST( _index, h_ )

static void
icvHoughLinesSDiv( const CvMat* img,
                   float rho, float theta, int threshold,
                   int srn, int stn,
                   CvSeq* lines, int linesMax )
{
    std::vector<uchar> _caccum, _buffer;
    std::vector<float> _sinTable;
    std::vector<int> _x, _y;
    float* sinTable;
    int *x, *y;
    uchar *caccum, *buffer;
    _CVLIST* list = 0;

#define _POINT(row, column)\
    (image_src[(row)*step+(column)])

    uchar *mcaccum = 0;
    int rn, tn;                 /* number of rho and theta discrete values */
    int index, i;
    int ri, ti, ti1, ti0;
    int row, col;
    float r, t;                 /* Current rho and theta */
    float rv;                   /* Some temporary rho value */
    float irho;
    float itheta;
    float srho, stheta;
    float isrho, istheta;

    const uchar* image_src;
    int w, h, step;
    int fn = 0;
    float xc, yc;

    const float d2r = (float)(Pi / 180);
    int sfn = srn * stn;
    int fi;
    int count;
    int cmax = 0;

    CVPOS pos;
    _index *pindex;
    _index vi;

    CV_Assert( CV_IS_MAT(img) && CV_MAT_TYPE(img->type) == CV_8UC1 );
    CV_Assert( linesMax > 0 && rho > 0 && theta > 0 );

    threshold = MIN( threshold, 255 );

    image_src = img->data.ptr;
    step = img->step;
    w = img->cols;
    h = img->rows;

    irho = 1 / rho;
    itheta = 1 / theta;
    srho = rho / srn;
    stheta = theta / stn;
    isrho = 1 / srho;
    istheta = 1 / stheta;

    rn = cvFloor( sqrt( (double)w * w + (double)h * h ) * irho );
    tn = cvFloor( 2 * Pi * itheta );

    list = h_create_list__index( linesMax < 1000 ? linesMax : 1000 );
    vi.value = threshold;
    vi.rho = -1;
    h_add_head__index( list, &vi );

    /* Precalculating sin */
    _sinTable.resize( 5 * tn * stn );
    sinTable = &_sinTable[0];

    for( index = 0; index < 5 * tn * stn; index++ )
        sinTable[index] = (float)cos( stheta * index * 0.2f );

    _caccum.resize(rn * tn);
    caccum = &_caccum[0];
    memset( caccum, 0, rn * tn * sizeof( caccum[0] ));

    /* Counting all feature pixels */
    for( row = 0; row < h; row++ )
        for( col = 0; col < w; col++ )
            fn += _POINT( row, col ) != 0;

    _x.resize(fn);
    _y.resize(fn);
    x = &_x[0];
    y = &_y[0];

    /* Full Hough Transform (it's accumulator update part) */
    fi = 0;
    for( row = 0; row < h; row++ )
    {
        for( col = 0; col < w; col++ )
        {
            if( _POINT( row, col ))
            {
                int halftn;
                float r0;
                float scale_factor;
                int iprev = -1;
                float phi, phi1;
                float theta_it;     /* Value of theta for iterating */

                /* Remember the feature point */
                x[fi] = col;
                y[fi] = row;
                fi++;

                yc = (float) row + 0.5f;
                xc = (float) col + 0.5f;

                /* Update the accumulator */
                t = (float) fabs( cvFastArctan( yc, xc ) * d2r );
                r = (float) sqrt( (double)xc * xc + (double)yc * yc );
                r0 = r * irho;
                ti0 = cvFloor( (t + Pi / 2) * itheta );

                caccum[ti0]++;

                theta_it = rho / r;
                theta_it = theta_it < theta ? theta_it : theta;
                scale_factor = theta_it * itheta;
                halftn = cvFloor( Pi / theta_it );
                for( ti1 = 1, phi = theta_it - halfPi, phi1 = (theta_it + t) * itheta;
                     ti1 < halftn; ti1++, phi += theta_it, phi1 += scale_factor )
                {
                    rv = r0 * _cos( phi );
                    i = cvFloor( rv ) * tn;
                    i += cvFloor( phi1 );
                    assert( i >= 0 );
                    assert( i < rn * tn );
                    caccum[i] = (uchar) (caccum[i] + ((i ^ iprev) != 0));
                    iprev = i;
                    if( cmax < caccum[i] )
                        cmax = caccum[i];
                }
            }
        }
    }

    /* Starting additional analysis */
    count = 0;
    for( ri = 0; ri < rn; ri++ )
    {
        for( ti = 0; ti < tn; ti++ )
        {
            if( caccum[ri * tn + ti] > threshold )
            {
                count++;
            }
        }
    }

    if( count * 100 > rn * tn )
    {
        icvHoughLinesStandard( img, rho, theta, threshold, lines, linesMax );
        return;
    }

    _buffer.resize(srn * stn + 2);
    buffer = &_buffer[0];
    mcaccum = buffer + 1;

    count = 0;
    for( ri = 0; ri < rn; ri++ )
    {
        for( ti = 0; ti < tn; ti++ )
        {
            if( caccum[ri * tn + ti] > threshold )
            {
                count++;
                memset( mcaccum, 0, sfn * sizeof( uchar ));

                for( index = 0; index < fn; index++ )
                {
                    int ti2;
                    float r0;

                    yc = (float) y[index] + 0.5f;
                    xc = (float) x[index] + 0.5f;

                    /* Update the accumulator */
                    t = (float) fabs( cvFastArctan( yc, xc ) * d2r );
                    r = (float) sqrt( (double)xc * xc + (double)yc * yc ) * isrho;
                    ti0 = cvFloor( (t + Pi * 0.5f) * istheta );
                    ti2 = (ti * stn - ti0) * 5;
                    r0 = (float) ri *srn;

                    for( ti1 = 0 /*, phi = ti*theta - Pi/2 - t */ ; ti1 < stn; ti1++, ti2 += 5
                         /*phi += stheta */  )
                    {
                        /*rv = r*_cos(phi) - r0; */
                        rv = r * sinTable[(int) (abs( ti2 ))] - r0;
                        i = cvFloor( rv ) * stn + ti1;

                        i = CV_IMAX( i, -1 );
                        i = CV_IMIN( i, sfn );
                        mcaccum[i]++;
                        assert( i >= -1 );
                        assert( i <= sfn );
                    }
                }

                /* Find peaks in maccum... */
                for( index = 0; index < sfn; index++ )
                {
                    i = 0;
                    pos = h_get_tail_pos__index( list );
                    if( h_get_prev__index( &pos )->value < mcaccum[index] )
                    {
                        vi.value = mcaccum[index];
                        vi.rho = index / stn * srho + ri * rho;
                        vi.theta = index % stn * stheta + ti * theta - halfPi;
                        while( h_is_pos__index( pos ))
                        {
                            if( h_get__index( pos )->value > mcaccum[index] )
                            {
                                h_insert_after__index( list, pos, &vi );
                                if( h_get_count__index( list ) > linesMax )
                                {
                                    h_remove_tail__index( list );
                                }
                                break;
                            }
                            h_get_prev__index( &pos );
                        }
                        if( !h_is_pos__index( pos ))
                        {
                            h_add_head__index( list, &vi );
                            if( h_get_count__index( list ) > linesMax )
                            {
                                h_remove_tail__index( list );
                            }
                        }
                    }
                }
            }
        }
    }

    pos = h_get_head_pos__index( list );
    if( h_get_count__index( list ) == 1 )
    {
        if( h_get__index( pos )->rho < 0 )
        {
            h_clear_list__index( list );
        }
    }
    else
    {
        while( h_is_pos__index( pos ))
        {
            CvLinePolar line;
            pindex = h_get__index( pos );
            if( pindex->rho < 0 )
            {
                /* This should be the last element... */
                h_get_next__index( &pos );
                assert( !h_is_pos__index( pos ));
                break;
            }
            line.rho = pindex->rho;
            line.angle = pindex->theta;
            cvSeqPush( lines, &line );

            if( lines->total >= linesMax )
                break;
            h_get_next__index( &pos );
        }
    }

    h_destroy_list__index(list);
}
Re[3]: профи или упоротый
От: __kot2  
Дата: 20.02.15 01:16
Оценка:
Здравствуйте, velkin, Вы писали:
V>Ну или разработчики OpenCV как вариант.
ну ни для кого тут сокретом не являются, думаю, что многий продакшен код такие вот макароны написанные левой ногой.
просто большинство обычных людей это касается только когда в таком стиле пишут OpenSSL и потом удивлются, что там глк на глюке. а так то такой это только проблема товарищей из opencv как они этот код будут расширять, отлаживать или портировать. да и если весь opencv таквоц то судя по всему opencv работает только из-за компенсации багов друг другом и только ра малине девелоперов и только на их примерах
Re[3]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 01:47
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

MR>>а нафига там goto, если у каждого цикла уже есть выражение для остановки, куда этот found и можно засунуть


J>уже лучше но всё равно костыль, гото там то что доктор прописал


Согласен, причём в книжках по С++ не запрещают писать goto, просто говорится, что в большинстве случаев это плохая практика. Об исключениях почему-то те кто учился потом забывают. Но мне стало интересно, и я включил поиск по OpenCV, причём не считаю разработчиков топовых библиотек упоротыми, даже если в принципе можно написать лучше. И вот один из обнаруженных примеров, то есть goto применяется, когда это необходимо.

А так, конечно, пусть люди расскажут, как выйти из двух вложенных циклов, при этом не теряя время на проверку условий. Когда-то давно уже думал над этим вопросом, и ничего кроме goto в голову не пришло, разве что перестроить алгоритм, если это возможно так, чтобы не надо было выходить.

Что касается return, то тогда для оптимизации придётся писать inline. А это повлечёт за собой определение в заголовочном файле, пусть даже завуалировано. И нужно же понимать, что разные люди пишут по-разному и даже до меня со временем стало доходить, что мои объектно-ориентированные техники на самом деле инструменты аналитики, и писать в них иногда крайне неразумно.

Пожалуй лишь обобщённое программирование (шаблоны C++) не теряет скорости работы при различных аналитических извращениях, но и у них есть свой алгоритмический предел. Опять же есть желание разбить всё на части, ввести тысяча пятьсот абстракций, но опыт работы и общение с другими программистами говорит, что так делать не стоит, так как во многих случаях это заканчивается плохо.

Для разбиения функция должна иметь повторно используемые части, но где же им взяться, если проект мелкий. Вот тут и попадаем в ловушку, в которой сишники чувствуют себя хорошо, а все остальные не очень. Хотя по идее оптимальнее всего совмещать разные парадигмы в зависимости от обстоятельств.

void cv::Canny( InputArray _src, OutputArray _dst,
                double low_thresh, double high_thresh,
                int aperture_size, bool L2gradient )
{
    Mat src = _src.getMat();
    CV_Assert( src.depth() == CV_8U );

    _dst.create(src.size(), CV_8U);
    Mat dst = _dst.getMat();

    if (!L2gradient && (aperture_size & CV_CANNY_L2_GRADIENT) == CV_CANNY_L2_GRADIENT)
    {
        //backward compatibility
        aperture_size &= ~CV_CANNY_L2_GRADIENT;
        L2gradient = true;
    }

    if ((aperture_size & 1) == 0 || (aperture_size != -1 && (aperture_size < 3 || aperture_size > 7)))
        CV_Error(CV_StsBadFlag, "");

    if (low_thresh > high_thresh)
        std::swap(low_thresh, high_thresh);

#ifdef HAVE_TEGRA_OPTIMIZATION
    if (tegra::canny(src, dst, low_thresh, high_thresh, aperture_size, L2gradient))
        return;
#endif

#ifdef USE_IPP_CANNY
    if( aperture_size == 3 && !L2gradient &&
        ippCanny(src, dst, (float)low_thresh, (float)high_thresh) )
        return;
#endif

    const int cn = src.channels();
    Mat dx(src.rows, src.cols, CV_16SC(cn));
    Mat dy(src.rows, src.cols, CV_16SC(cn));

    Sobel(src, dx, CV_16S, 1, 0, aperture_size, 1, 0, cv::BORDER_REPLICATE);
    Sobel(src, dy, CV_16S, 0, 1, aperture_size, 1, 0, cv::BORDER_REPLICATE);

    if (L2gradient)
    {
        low_thresh = std::min(32767.0, low_thresh);
        high_thresh = std::min(32767.0, high_thresh);

        if (low_thresh > 0) low_thresh *= low_thresh;
        if (high_thresh > 0) high_thresh *= high_thresh;
    }
    int low = cvFloor(low_thresh);
    int high = cvFloor(high_thresh);

    ptrdiff_t mapstep = src.cols + 2;
    AutoBuffer<uchar> buffer((src.cols+2)*(src.rows+2) + cn * mapstep * 3 * sizeof(int));

    int* mag_buf[3];
    mag_buf[0] = (int*)(uchar*)buffer;
    mag_buf[1] = mag_buf[0] + mapstep*cn;
    mag_buf[2] = mag_buf[1] + mapstep*cn;
    memset(mag_buf[0], 0, /* cn* */mapstep*sizeof(int));

    uchar* map = (uchar*)(mag_buf[2] + mapstep*cn);
    memset(map, 1, mapstep);
    memset(map + mapstep*(src.rows + 1), 1, mapstep);

    int maxsize = std::max(1 << 10, src.cols * src.rows / 10);
    std::vector<uchar*> stack(maxsize);
    uchar **stack_top = &stack[0];
    uchar **stack_bottom = &stack[0];

    /* sector numbers
       (Top-Left Origin)

        1   2   3
         *  *  *
          * * *
        0*******0
          * * *
         *  *  *
        3   2   1
    */

    #define CANNY_PUSH(d)    *(d) = uchar(2), *stack_top++ = (d)
    #define CANNY_POP(d)     (d) = *--stack_top

    // calculate magnitude and angle of gradient, perform non-maxima supression.
    // fill the map with one of the following values:
    //   0 - the pixel might belong to an edge
    //   1 - the pixel can not belong to an edge
    //   2 - the pixel does belong to an edge
    for (int i = 0; i <= src.rows; i++)
    {
        int* _norm = mag_buf[(i > 0) + 1] + 1;
        if (i < src.rows)
        {
            short* _dx = dx.ptr<short>(i);
            short* _dy = dy.ptr<short>(i);

            if (!L2gradient)
            {
                for (int j = 0; j < src.cols*cn; j++)
                    _norm[j] = std::abs(int(_dx[j])) + std::abs(int(_dy[j]));
            }
            else
            {
                for (int j = 0; j < src.cols*cn; j++)
                    _norm[j] = int(_dx[j])*_dx[j] + int(_dy[j])*_dy[j];
            }

            if (cn > 1)
            {
                for(int j = 0, jn = 0; j < src.cols; ++j, jn += cn)
                {
                    int maxIdx = jn;
                    for(int k = 1; k < cn; ++k)
                        if(_norm[jn + k] > _norm[maxIdx]) maxIdx = jn + k;
                    _norm[j] = _norm[maxIdx];
                    _dx[j] = _dx[maxIdx];
                    _dy[j] = _dy[maxIdx];
                }
            }
            _norm[-1] = _norm[src.cols] = 0;
        }
        else
            memset(_norm-1, 0, /* cn* */mapstep*sizeof(int));

        // at the very beginning we do not have a complete ring
        // buffer of 3 magnitude rows for non-maxima suppression
        if (i == 0)
            continue;

        uchar* _map = map + mapstep*i + 1;
        _map[-1] = _map[src.cols] = 1;

        int* _mag = mag_buf[1] + 1; // take the central row
        ptrdiff_t magstep1 = mag_buf[2] - mag_buf[1];
        ptrdiff_t magstep2 = mag_buf[0] - mag_buf[1];

        const short* _x = dx.ptr<short>(i-1);
        const short* _y = dy.ptr<short>(i-1);

        if ((stack_top - stack_bottom) + src.cols > maxsize)
        {
            int sz = (int)(stack_top - stack_bottom);
            maxsize = maxsize * 3/2;
            stack.resize(maxsize);
            stack_bottom = &stack[0];
            stack_top = stack_bottom + sz;
        }

        int prev_flag = 0;
        for (int j = 0; j < src.cols; j++)
        {
            #define CANNY_SHIFT 15
            const int TG22 = (int)(0.4142135623730950488016887242097*(1<<CANNY_SHIFT) + 0.5);

            int m = _mag[j];

            if (m > low)
            {
                int xs = _x[j];
                int ys = _y[j];
                int x = std::abs(xs);
                int y = std::abs(ys) << CANNY_SHIFT;

                int tg22x = x * TG22;

                if (y < tg22x)
                {
                    if (m > _mag[j-1] && m >= _mag[j+1]) goto __ocv_canny_push;
                }
                else
                {
                    int tg67x = tg22x + (x << (CANNY_SHIFT+1));
                    if (y > tg67x)
                    {
                        if (m > _mag[j+magstep2] && m >= _mag[j+magstep1]) goto __ocv_canny_push;
                    }
                    else
                    {
                        int s = (xs ^ ys) < 0 ? -1 : 1;
                        if (m > _mag[j+magstep2-s] && m > _mag[j+magstep1+s]) goto __ocv_canny_push;
                    }
                }
            }
            prev_flag = 0;
            _map[j] = uchar(1);
            continue;
__ocv_canny_push:
            if (!prev_flag && m > high && _map[j-mapstep] != 2)
            {
                CANNY_PUSH(_map + j);
                prev_flag = 1;
            }
            else
                _map[j] = 0;
        }

        // scroll the ring buffer
        _mag = mag_buf[0];
        mag_buf[0] = mag_buf[1];
        mag_buf[1] = mag_buf[2];
        mag_buf[2] = _mag;
    }

    // now track the edges (hysteresis thresholding)
    while (stack_top > stack_bottom)
    {
        uchar* m;
        if ((stack_top - stack_bottom) + 8 > maxsize)
        {
            int sz = (int)(stack_top - stack_bottom);
            maxsize = maxsize * 3/2;
            stack.resize(maxsize);
            stack_bottom = &stack[0];
            stack_top = stack_bottom + sz;
        }

        CANNY_POP(m);

        if (!m[-1])         CANNY_PUSH(m - 1);
        if (!m[1])          CANNY_PUSH(m + 1);
        if (!m[-mapstep-1]) CANNY_PUSH(m - mapstep - 1);
        if (!m[-mapstep])   CANNY_PUSH(m - mapstep);
        if (!m[-mapstep+1]) CANNY_PUSH(m - mapstep + 1);
        if (!m[mapstep-1])  CANNY_PUSH(m + mapstep - 1);
        if (!m[mapstep])    CANNY_PUSH(m + mapstep);
        if (!m[mapstep+1])  CANNY_PUSH(m + mapstep + 1);
    }

    // the final pass, form the final image
    const uchar* pmap = map + mapstep + 1;
    uchar* pdst = dst.ptr();
    for (int i = 0; i < src.rows; i++, pmap += mapstep, pdst += dst.step)
    {
        for (int j = 0; j < src.cols; j++)
            pdst[j] = (uchar)-(pmap[j] >> 1);
    }
}
Re[2]: Re: профи или упоротый
От: Serg27  
Дата: 20.02.15 03:54
Оценка:
Прекрасный анализ этого куска кода.
Я, честно говоря, дошел в коде только до места с бинаризацией изображения (где магическое число "160"), дальше не стал смотреть. Проблема с goto тут самая последняя. В общем-то как код на один раз сойдет (как уже писали), но меня смущает прекрасное оформление этого кода. То ли корпоративные стандарты оформления свято блюдутся даже для одно-минутных поделок, то ли код был написан в исследовательских целях на matlabe (например) каким-то экспертом, а затем был перенесен на C++ уже другим человеком, которому дали это свыше как "божественное откровение". Склоняюсь ко второму варианту, так как наблюдал такое не однократно.
Re[4]: профи или упоротый
От: Kernan Ниоткуда https://rsdn.ru/forum/flame.politics/
Дата: 20.02.15 07:52
Оценка:
Здравствуйте, pestis, Вы писали:

P>Это низкоуровневая обработка изображений. Ее вообще нужно писать на чистом С хорошим оптимизирующим компилятором. Просто разработчики OpenCV в основной массе школьники, копипастящие алгоритмы из учебников.

Ничего не надо писать на С. Везде можно использовать С++ и по производительности он будет как С-шный код если ты умеешь писать на С++.
Sic luceat lux!
Re[5]: профи или упоротый
От: Molchalnik  
Дата: 20.02.15 08:23
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>можно и функцию но тогда будет множество мелких функций, тут как я вижу одна функция не требующая её дробить еще на несколько функций


Видать, ты старой школы, сейчас причины для дробления функции — читаемость и логический уровень. инлайн решает проблемы скорости.
Re[5]: профи или упоротый
От: Evgeny.Panasyuk Россия  
Дата: 20.02.15 09:07
Оценка:
Здравствуйте, Kernan, Вы писали:

K>Везде можно использовать С++ и по производительности он будет как С-шный код если ты умеешь писать на С++.


Вообще-то нормальный C++ код будет быстрее, за счёт бесплатных абстракций.
Adobe/Boost — Generic Image Library
Re[3]: профи или упоротый
От: Кодт Россия  
Дата: 20.02.15 09:56
Оценка:
Здравствуйте, velkin, Вы писали:

V>Ну или разработчики OpenCV как вариант.


Такое впечатление, что разработчики OpenCV просто перепёрли сишный код на плюсы — да и то, лишь ради самоочистки пяти локальных массивов.
Перекуём баги на фичи!
Re[6]: профи или упоротый
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.02.15 11:20
Оценка:
Здравствуйте, __kot2, Вы писали:

V>>А по мне так OpenCV прекрасно работает, и даже с CUDA нет никаких проблем.

__>я не в курсе как он работет, если честно.

Хорошо работает, не идеально, но хорошо. Причина: тесты, огромная база пользователей, поддержка множества платформ (как программных, так и аппаратных).

__>у со своей колокольни кому сказать что куча научного софта на самом деле гавно, которое прдюсит невалидный кал огромных обьемов, загрязнящий что то осмысленное. кал этот совершенно бесполезно испавлять. только его аффтар понимает в этих макаронах хоть что-то. это называется job security, да, когда только тпкущие разработчики могут что-то там сделать, а остальные потеряются где-то пытаясь понять что имелось в виду во всей вот этой вот бадяге.


Куча научного софта реализует достаточно сложные алгоритмы, которые даже идеально написанные будут непонятны без глубокого знания бэкграунда.
Re[4]: профи или упоротый
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.02.15 11:22
Оценка:
Здравствуйте, Кодт, Вы писали:

V>>Ну или разработчики OpenCV как вариант.


К>Такое впечатление, что разработчики OpenCV просто перепёрли сишный код на плюсы — да и то, лишь ради самоочистки пяти локальных массивов.


Это было верно для OpenCV 2.xx. Там как раз начало появляться С++ API. Собственно, поэтому поводу версия и сменилась на двойку.
Для версии 3.хх твоё утверждение уже не верно.
Re[4]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 14:28
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Такое впечатление, что разработчики OpenCV просто перепёрли сишный код на плюсы — да и то, лишь ради самоочистки пяти локальных массивов.


Код действительно перенесли на С++ с Си, у них там образовалось два варианта использования.

Но что-то читая комментарии навязчиво всплывает в памяти тема А вы видели код не говно ?
Автор:
Дата: 12.01.13
. А то уже и Qt с этой позиции обсудили. Надо будет stl и boost как-нибудь запостить, интересно так же было бы узнать, что скажут о crypto++.
Re[7]: профи или упоротый
От: __kot2  
Дата: 20.02.15 14:29
Оценка:
Здравствуйте, Nuzhny, Вы писали:
N>Хорошо работает, не идеально, но хорошо. Причина: тесты, огромная база пользователей, поддержка множества платформ (как программных, так и аппаратных).
обычо жизненный цикл подобных проектов таков:
из за всех этих захаржкоженных констант и спагеттей багов там конечно навалом. но так как сами результаты нечеткие в глаза это так не бросается. но конечн люди их фиксят потихоньку. однако из-за невозможности понять реальную причину бага будут фиксить симптоматически. если из ф-ии выходит 2, а нужно 3, то вставят просто if после ф-ии, который инкрементит результат. в итоге через несколько лет код так усложнится, что люди годами будут занимться только какими-то рефакторингом не сдвигаясь с места. как например с Нетскейпом было. Пройдут годы, рефакторинг так и не закончится, а opencv будет забыт и замещен другим продуктом. может потом, когда команда говнарей полностью сменится, то проект вынырнет из проруби и снова получит некую популярность, как это стало с Netscape-Mozilla-Firefox. но уже позднвато будет. а все потому что ручки кривые у текущих программистов

__>>у со своей колокольни кому сказать что куча научного софта на самом деле гавно, которое прдюсит невалидный кал огромных обьемов, загрязнящий что то осмысленное. кал этот совершенно бесполезно испавлять. только его аффтар понимает в этих макаронах хоть что-то. это называется job security, да, когда только тпкущие разработчики могут что-то там сделать, а остальные потеряются где-то пытаясь понять что имелось в виду во всей вот этой вот бадяге.


N>Куча научного софта реализует достаточно сложные алгоритмы, которые даже идеально написанные будут непонятны без глубокого знания бэкграунда.

когда делаешь всегда надо понимать смысл того что делаешь. если общего смысла не видно, то его и искать не стоитю нет его. просто какая-то подгонметрия под нужные результаты
Re[8]: профи или упоротый
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 20.02.15 14:35
Оценка:
Здравствуйте, __kot2, Вы писали:

__>обычо жизненный цикл подобных проектов таков:

__>из за всех этих захаржкоженных констант и спагеттей багов там конечно навалом. но так как сами результаты нечеткие в глаза это так не бросается. но конечн люди их фиксят потихоньку. однако из-за невозможности понять реальную причину бага будут фиксить симптоматически. если из ф-ии выходит 2, а нужно 3, то вставят просто if после ф-ии, который инкрементит результат. в итоге через несколько лет код так усложнится, что люди годами будут занимться только какими-то рефакторингом не сдвигаясь с места. как например с Нетскейпом было. Пройдут годы, рефакторинг так и не закончится, а opencv будет забыт и замещен другим продуктом. может потом, когда команда говнарей полностью сменится, то проект вынырнет из проруби и снова получит некую популярность, как это стало с Netscape-Mozilla-Firefox. но уже позднвато будет. а все потому что ручки кривые у текущих программистов

Ну, прямо с OpenCV такая ситуация вряд ли сложится.
Он, во-первых, не так плохо написан.
Во-вторых, он модульный, очень даже хорошо модульный. Не какая-то единая библиотека, а набор библиотек.
В-третьих, вменяемых альтернатив пока не видно.
Re[9]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 16:20
Оценка:
Здравствуйте, Nuzhny, Вы писали:

N>Во-вторых, он модульный, очень даже хорошо модульный. Не какая-то единая библиотека, а набор библиотек.


OpenCV можно воспринимать даже не как набор библиотек, а как набор независимых друг от друга функций, для удобства разделённых на модули. Для пользователя это значит сверхнизкий порог входа.

N>В-третьих, вменяемых альтернатив пока не видно.


Судя по описанию OpenCV клиенты и поддержка была от Intel, NVidia, Microsoft. Предположу, что это IPP, CUDA и Kinect. Альтернативы есть, но гораздо более слабые, причём речь идёт о наличии огромного количества функционала.

Могу так же предположить, что сделай они изначально всё на шаблонах C++, у них бы получилось лучше. Проблема в том, что при таком подходе OpenCV скорее всего бы загнулся, так как помимо предметной области возникла бы потребность в изучении очень мощных программных концепций. Это в свою очередь повлекло бы поиск специалистов, что крайне затруднительно в условиях, когда нет постоянных источников дохода.
Re[8]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 21:20
Оценка:
Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>Это где же жёсткая кодогенерация у Страуструпа? Его книжки как раз подходят новичкам.


А вот и зря, ещё в 1999 году его купил, Язык программирования С++ 3-е издание. Его можно рассматривать как отличный справочник, но не как учебное пособие. Моё мнение, человек начитавшись Страуструпа освоит языковые конструкции, голый синтаксис, но третья часть "Стандартная библиотека" не даст понимания глубинного смысла всего этого действа. Жёсткая кодогенерация в Александреску. Вместо Страуструпа можно было бы прочитать словарь по английскому языку, начиная от A до Z. Тоже польза, если хочешь стать языковым экспертом, но удастся ли заговорить сделав лишь это?

EP>А Майерс это вообще что-то типа common pitfalls, а не учебник.


У меня это идёт как-то так:
Наиболее эффективное использование C++ 35 новых способов улучшить стиль программирования 1-е издание
Эффективное использование C++ 50 рекомендаций по улучшению ваших программ и проектов 2-е издание
Эффективное использование STL (речь об этой книге)

Проблема в том, что все его материалы даны в виде советов, даже про STL. Сначала мне думается нужно научиться использовать STL и понять его смысл, а уже потом изучать советы как дополнение.

Мне просто непонятно, почему хают кодогенерацию называя её медленной, вот и размышляю. По всем прикидкам скорость исполнения программ такая же как в Си, но выражения гораздо более лаконичные и вкладываются друг в друга. Просто генератор, ничего сверхъестественного. Понятно, что не всем по вкусу, но так и против истины идти не нужно.
Re[9]: профи или упоротый
От: velkin Удмуртия https://kisa.biz
Дата: 20.02.15 22:12
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Из дурацких книг по С++ отдельно могу отметить "решение несуществующих задач" Саттера.


У меня в коллекции Саттер Герб:
Новые сложные задачи на C++ 40 новых головоломных примеров с решениями
Решение сложных задач на C++ 87 головоломных примеров с решениями
Стандарты программирования на C++ 101 правило и рекомендация

Это видимо вольная интерпретация, так же как "Новые несуществующие задачи на C++".
Re[9]: профи или упоротый
От: Evgeny.Panasyuk Россия  
Дата: 20.02.15 22:40
Оценка:
Здравствуйте, __kot2, Вы писали:

__>Здравствуйте, Evgeny.Panasyuk, Вы писали:

EP>>Это где же жёсткая кодогенерация у Страуструпа? Его книжки как раз подходят новичкам. А Майерс это вообще что-то типа common pitfalls, а не учебник.
__>Страуструп может представлять только исторический интерес. Глядя на его код просто умиляешься, как будто "Повесть о полку Игореве" читаешь.

Это про какой код, и чему конкретно умиляешься?
У него есть свежие издания книг. Да и в TC++PL старого третьего издания ничего ужасного/ветхого не помню (с поправкой на старый стандарт)
Re[10]: профи или упоротый
От: Nuzhny Россия https://github.com/Nuzhny007
Дата: 21.02.15 05:31
Оценка:
Здравствуйте, velkin, Вы писали:

N>>Во-вторых, он модульный, очень даже хорошо модульный. Не какая-то единая библиотека, а набор библиотек.

V>OpenCV можно воспринимать даже не как набор библиотек, а как набор независимых друг от друга функций, для удобства разделённых на модули. Для пользователя это значит сверхнизкий порог входа.

Почти так. Сейчас это набор функций и классов с зависимостью от opencv_core, в котором реализована матричная математика.

N>>В-третьих, вменяемых альтернатив пока не видно.

V>Судя по описанию OpenCV клиенты и поддержка была от Intel, NVidia, Microsoft. Предположу, что это IPP, CUDA и Kinect. Альтернативы есть, но гораздо более слабые, причём речь идёт о наличии огромного количества функционала.

Intel и AMD своими силами пилят OpenCL часть. NVidia добавила поддержку CUDA, есть отдельная ветка чисто для Tegra. Майкрософт, вроде, ничего не делает, поддержкой Кинекта занимается сам ITSeez, так как у них основной бизнес — навигация мобильных роботов.
OpenCV сейчас стал практически стандартом в своей области, тот же Khronos разрабатывал openvx с оглядкой на OpenCV.

V>Могу так же предположить, что сделай они изначально всё на шаблонах C++, у них бы получилось лучше. Проблема в том, что при таком подходе OpenCV скорее всего бы загнулся, так как помимо предметной области возникла бы потребность в изучении очень мощных программных концепций. Это в свою очередь повлекло бы поиск специалистов, что крайне затруднительно в условиях, когда нет постоянных источников дохода.


Изначально OpenCV была открытой альтернативой IPP, но медленной, глючной с небольшим числом добавочного функционала. А потом, когда Интел отказался от разработки, развитие пошло как снежный ком.
Re: профи или упоротый
От: Lepsik Индия figvam.ca
Дата: 23.02.15 18:49
Оценка:
Здравствуйте, jyuyjiyuijyu, Вы писали:

J>goto? не, не слышал


такой стиль у людей не пишуших унит тесты.

При написании юнит тестов не то что goto но и break — редкая операция.

Как следствие — у тебя будут exception сплош; и рядом — хотя бы из-за отсутсвия проверок по диапазонам.

Такой код нормальное код-ревю не пройдет
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.