Yurin's home page
My graduate students
How to program
Basic Literature
Important links
Some notes on Computer Vision topics
Current C++ codes
Research problems for students
|
Dmitry V. Yurin personal page
Как программировать, на чем, что читать, какие пакеты использовать:
Выбор языка программирования
Что читать по программированию
Как документировать программы
Языки программирования
Главный принцип - язык программирования должен соответствовать решаемой задаче.
АЛГОРИТМЫ, предназначенные для обработки изображений целесообразно писать на С++, с широким использованием шаблонов и методов метапрограммирования. Как минимум это касается низкоуровневых алгоритмов, которые что-то делают с ПИКСЕЛЯМИ изображения. Пикселей много, и понятно, что здесь необходимо задумываться об эффективности кода, даже не потому, чтобы добиться максимального быстродействия, а потому, что просто иначе программу нельзя будет нормально отлаживать (пусть например время обработки изображения больше часа, сколько потребуется потратить времени, чтобы найти ошибку?).
Каким требованиям должен удовлетворять язык программирования?
Он должен быть объектным. Иначе начинают плодиться глобальные переменные, и программа становится неуправляемой, невозможно понять, где поменялось значение такой переменной. Доступ-то до нее имеют все части кода! Попытка делать "объектность" путем структур и отдельных функций - несколько сужают количество подозреваемых, но все равно, 50 функций принимают указатель на эту структуру, где поменялось ее поле х?
Он должен быть шаблонным. Изображения бывают не только с яркостью от 0 до 255 !!! Современные цифровые фотоаппараты и сканеры дают и 10, и 12 и 16 битные изображения, кроме того, для ряда обработок (например, преобразование Фурье) данные ДОЛЖНЫ быть с плавающей точкой, для многих других методов обработки УДОБНО работать с числами с плавающей точкой. Тогда зачем одно и то же писать в нескольких вариантах? Более того, шаблоны подставляются (имплементируются) во время компиляции. Предположим, возникла задача проинтегрировать sin(x) от a до b. Функция интегрирования понятно должна быть написана один раз, а не по отдельности для каждого вида подинтегрального выражения. С точки зрения процедурного подхода - есть только одно решение, передать в эту функцию адрес функции подинтегрального выражения. Это каждый раз обращение по какому-то адресу памяти, даже для упомянутого синуса, который является ВСТРОЕННОЙ функцией процессора (т.е. одной ассемблерной командой). Этим Вы вынуждаете компилятор создать отдельную функцию (которая будет содержать одну строку - вычисление синуса и возврат) и каждый раз обращаться по памяти туда, где в памяти такая функция размещена. С другой стороны, при шаблонно проектировании, по шаблону функции интегрирования можно позволить компилятору создавать различные версии интегрирования конкретных функций, если они невелики - то они буду встроены непосредственно в код интегрирования. Размер программы несколько возрастет (вряд ли Вам потребуется вычислить 1000000 интегралов от различных функций), а скорость исполнения может существенно повыситься.
Он должен быть стандартным. Алгоритм обработки изображения - это вычислительный алгоритм. Нет смысла его ограничивать Windows, Microsoft или Borland. Иногда, но далеко не всегда, может быть целесообразно некоторые части алгоритма ограничивать 32- или 64 битной платформой. Поэтому не следует использовать специфические возможности и функции разных систем и компиляторов. Язык тоже должен иметь устойчивый стандарт. В этом отношении например C# - это сразу ограничение Windows/Microsoft Visual Studio и кроме того скорее всего придется постоянно переписывать код в соответствии с изменениями в языке.
Он должен быть мощным и выразительным. Говорят, если писать на C#, по скорости мы проиграем мало, процентов на 10-20. Но! Для этого надо соответствующие блоки кода писать в unsafe моде. Вы же остаетесь без инструментария! Арифметики и указатели и все, как в старом С. А на C++ это классы, шаблоны, виртуальные методы, методы мета программирования, библиотека STL и много других полезных библиотек.
Он должен быть позволять использовать доступные открытые коды. На С++ - масса доступных библиотек. Это и очень мощная библиотека BOOST (http://www.boost.org), которая содержит коды и общего назначения (например, работа с файлами) и работу с матрицами (uBLAS), и работу с графами и многое другое. Это библиотека LOKI с методами метоапрограммирования. Это библиотеки вычислительной математики, такие как netlib, Numerical recipes, lapack. Подобные библиотеки под C#, как правило, отсутствуют, встречаются только некоторые фрагменты, которые непонятно кем и как написаны.
Не следует забывать и о том, что большинство исследователей, работающих в области обработки изображений и сигналов, выкладывают свои коды в широкий доступ. Эти коды в подавляющем большинстве случаев написаны либо на С/С++ либо на MatLab.
С другой стороны, если требуется написать ГРОАФИЧЕСКИЙ ИНТЕРФЕЙС, то это уже системно зависимая вещь. В среде Windows в настоящее время написание интерфейса на С++ (например MFC) следует считать ошибкой. Он не будет иметь современного вида (например добраться из С++ до некоторых элементов управления весьма проблематично) и затраты труда непропорционально велики. Можно конечно пытаться написать свой элемент управления на С++ и он будет работать быстрее, чем написанный на С#, но это займет несколько месяцев, против пары дней на C#. Стоит ли результат таких затрат труда? Или, например, требуется считать данные из 1 файла в сетке. На C# - это несколько строк кода, а на С++ ... Вот если требуется обрабатывать десятки тысяч удаленных файлов, то надо бороться за скорость и писать на С++.
Вообще говоря, главными достоинствами C# являются
Удобство написание интерфейсов и очень удобный Wizard в Visual Studio.
Впервые для Windows - полноценная библиотека, дающая доступ до системных возможностей (что-то нарисовать, поработать с файлами, добраться куда-то по сети и т.п.) необходимости писать много килобайт кода.
Легкость стыковки с кодом написанном на С/С++ (для этого есть Managed C++)
В настоящий момент имеется даже встроенный интерпретатор - можно написать свою программу в которой предоставить пользователю возможность по программировать, это сейчас востребовано и ценится.
Другой хороший вариант - использование портируемых библиотек. Например Qt, которая переносима Windows/UNIX . Она на С++, но набор классов для написания интерфейсов организован весьма элегантно. Размер кода, который надо написать - с MFC несопоставимо меньше и читабельнее. Возможно, правда, внешне под Windows интерфейс будет выглядеть не столь современно, но не обычно, дело вкуса.
Если надо что-то один раз быстро прикинуть, посчитать, нарисовать график и посмотреть - то лучшее решение Matlab. Было бы дикостью создавать свой элемент управления, чтобы один раз построить график и выкинуть. На Matlab все можно сделать сразу, а свой график на C#/C++ средствами рисования Windows придутся сочинять много дней! Или он будет совсем кривой и непонятно - это результат или баг?
|