Home     People     Activities     Research     Publications    

 

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 придутся сочинять много дней! Или он будет совсем кривой и непонятно - это результат или баг?