nmpp
Функции

Исполняет разделение бинарной картинки на односвязные области. Пример вызова: no=VL_FloodFill32b(pSrcImage, Tetr,Image, pTmpBuff, nSrcWidth, nSrcHeight);. Подробнее...

Функции

int nmppiFloodFill (unsigned int *pSrcImage, SegmentInfo *pSegmentInfo, unsigned int *pSegmentImage, int nWidth, int nHeight, unsigned int *pTmpBuff)
 
int FloodFill8 (void *src, void *dst, int nWidth, int nHeight, spot_struct *spot, int lenSpot, unsigned *pixels, int mSpot, int dtFull, int dtSpot, int lDiag, int lDropSpot, ds_struct *dropSpot, int nPxlMin, int nPxlMax, int dXYmin, int dXYmax)
 Функция FloodFill8 выполняет поиск пятен (сегментов, односвязных областей) во входной 8-битной матрице (изображения в градациях серого от 0 до 255), и строит такие же пятна в выходной матрице, заполняя их одним и тем же значением (цветом, соответствующим номеру пятна). Подробнее...
 

Подробное описание

Исполняет разделение бинарной картинки на односвязные области. Пример вызова: no=VL_FloodFill32b(pSrcImage, Tetr,Image, pTmpBuff, nSrcWidth, nSrcHeight);.

Аргументы
pSrcImageВходное изображение
pSegmentInfoмассив структур, где содержатся минимальные и максимальные координаты прямоугольника, описывающего сегментированную область.
nWidthширина изображения
nHeightвысота изображения
pTmpBuffВременный массив. Его размер должен быть 2*nWidth*nHeight
Возвращаемые значения
pSegmentImageРезультирующее "изображение", где все точки одного сегмента имеют одинаковое значение (1,...)
Возвращает
Число сегментов на изображении
Заметки
Массив pSegmentImage дожен быть обнулен. Функция изменяет массив pSrcImage.

Функции

◆ FloodFill8()

int FloodFill8 ( void *  src,
void *  dst,
int  nWidth,
int  nHeight,
spot_struct spot,
int  lenSpot,
unsigned *  pixels,
int  mSpot,
int  dtFull,
int  dtSpot,
int  lDiag,
int  lDropSpot,
ds_struct dropSpot,
int  nPxlMin,
int  nPxlMax,
int  dXYmin,
int  dXYmax 
)

Функция FloodFill8 выполняет поиск пятен (сегментов, односвязных областей) во входной 8-битной матрице (изображения в градациях серого от 0 до 255), и строит такие же пятна в выходной матрице, заполняя их одним и тем же значением (цветом, соответствующим номеру пятна).

Аргументы
srcвходная 8-битная матрица размером nHeight x nWidth.
Внимание. Входная матрица src модифицируется:
  • в целях оптимизации программы обнуляются верхняя и нижняя строки, и крайний левый и крайний правый столбцы (границы матрицы),
  • в процессе обработки найденные пятна обнуляются.
dstрезультирующая 8-битная матрица того же размера nHeight x nWidth.
Внимание. Перед обращением к функции выходная матрица dst должна быть обнулена.
nWidthширина входной (и выходной) матрицы в 8-битных элементах.
Ограничения. Ширина матрицы должна быть кратна 32-битным словам: nWidth - положительное, (nWidth & 3) = 0.
nHeightвысота входной (и выходной) матрицы.
Ограничения. Высота матрицы не должна превышать 1080 строк: nHeight - положительное, (nHeight <= 1080). Это ограничение можно обойти задав в начале файла FloodFill8.asm вместо 1080 нужное значение константы: const NHEIGHT = 1080;
spotмассив, содержащий обобщенную информацию о найденных пятнах – минимально 6 параметров формата int для каждого пятна: Замечание1. Чтобы гарантированно избежать переполнения массива spot в общем случае (когда характер матрицы, количество, размер пятен неизвестны, и не задан параметр mSpot>0), размер массива spot в 32-битных словах должен быть: ( nSpotMax + 1 + [(nSpotMax-1)/255] ) * lenSpot, nSpotMax = [(nHeight-2)*(nWidth-2)/2 + 0.5], при lDiag=0, = [(nHeight-2)/2+0.5] * [(nWidth-2)/2+0.5], при lDiag=1, квадратные скобки [...] обозначают целую часть числа, напомним: 2 строки и 2 солбца входной матрицы обнулены. Замечание2. Если задан параметр mSpot>0, то массив spot достаточно определить для mSpot пятен (mSpot задается с учетом служебного и фиктивных пятен).
lenSpotразмер пятна в 32-битных словах, позволяет задать размер пятна более 6 слов, резервируя место для дополнительных параметров пятна довычисляемых другими функциями (например, угол наклона пятна к горизонтальной оси…).
Замечание. Если параметр lenSpot задан некорректно lenSpot<6, то ему присваивается минимальное возможное значение lenSpot=6.
pixelsмассив координат пикселов, принадлежащих найденным пятнам, каждый элемент массива состоит из одного 32 битного слова, включающего в себя координаты пиксела в матрице src (или dst): unsigned int ij; биты [31..16] - i - номер строки, биты [15..0] - j - номер столбца. (Отсюда ограничение: nHeight, nWidth не могут быть больше 2**16-1 = 65535).
Замечание. В общем случае (когда заранее неизвестно о количестве и размерах пятен в матрице), чтобы гарантированно избежать переполнения массива pixels, его размер должен быть (nHeight-2)*(nWidth-2) 32-битных слов (что почти в 4 раза больше входной 8-битной матрицы, напомним: 2 строки и 2 солбца входной матрицы обнулены).
mSpotчисло пятен, ограничивающее поиск. Если задано mSpot>0, то после обработки очередного пятна проверяется: достигло ли количество найденных пятен nSpot заданного mSpot (mSpot<=nSpot)? Если «Да», то происходит (принудительный) выход из программы с записью в spot[0].Ymin=2. Если задано mSpot=0, то проверок на количество найденных пятен не производится.
Замечание1. Если задать mSpot<=255, то пятна будут однозначно соответствовать своим номерам, то есть не будет пятен с повторяющимися номерами.
Замечание2. mSpot следует задавать с учетом служебного пятна (с номером 0) и фиктивных пятен (с номерами 256,512,768...), то есть, если поиск надо ограничить нахождением первых mSpotReal>0 пятен, то mSpot = 1 + mSpotReal + [(mSpotReal-1)/255] квадратные скобки [...] обозначают целую часть числа
dtFullвремя, выделенное на работу программы (в тактах процессора). Если задано dtFull>0, то после обработки очередного пятна (и в конце каждой строки) проверяется: осталось ли время на обработку следующего пятна dtRest<dtSpot? (dtRest=dtFull-(T-T0), T – текущее время, T0 – начало работы программы). Если «Нет», то происходит выход из программы с записью в spot[0].Ymin=1. Если задано dtFull=0, то проверок на достаточность времени на обработку следующего пятна не производится.
Замечание1. Задание dtFull>0 маленьким может значительно сократить время работы программы, однако, не гарантирует корректного завершения программы (например, когда обрабатываемое пятно занимает всю оставшуюся часть матрицы).
Замечание2. При выборе значения dtFull следует учитывать время обработки типового пятна dtSpot.
dtSpotвремя обработки типового пятна (в тактах процессора). Используется совместно с параметром dtFull при оценке достаточного времени на обработку следующего пятна.
Ограничение. Если задано dtFull>0, то dtSpot должно быть меньше него: dtSpot - неотрицательное, (dtFull>0)&&(dtSpot<dtFull).
lDiagпараметр, определяющий связность пятна по диагоналям:
  • lDiag=0 - элементы являются соседними, если они граничат или по вертикали, или по горизонтали (по ходам ладьи, но не по ходам слона),
  • lDiag=1 - элементы являются соседними, если они граничат или по вертикали, или по горизонтали, или по диагоналям (по ходам ферзя).

Замечание. Как показывает практика, результат обработки видеоизображений существенно не зависит от параметра lDiag, но при lDiag=1 значительно увеличивает время работы функции. Если нет особой необходимости, рекомендуется задавать lDiag=0.
lDropSpotпараметр, задающий необходимость отбраковки найденных пятен по условиям НЕвхождения числа пикселов или размеров пятна в заданные диапазоны (см. ниже параметры nPxlmin, nPxlmax, dXYmin, dXYmax), статистика по отбракованным пятнам ведется в массиве dropSpot.
lDropSpot=0 – найденные пятна НЕ отбраковываются, то есть все найденные пятна учитываются в массивах spot, pixels и отмечаются в выходной матрице dst,
lDropSpot=1 – пятна с числом пикселов или размеров пятна не попадающими в заданные диапазоны отбраковываются, то есть не учитываются в массивах spot, pixels и не отмечаются в выходной матрице dst, статистика по отбракованным пятнам ведется в массиве dropSpot.
Замечание. Задание параметра lDropSpot=1 приводит к увеличению работы функции и требует выделения памяти для массива dropSpot. Если нет особой необходимости, задавайте lDropSpot=0.
dropSpot– массив, в который опционально собирается статистика по отбракованным пятнам: на каждый из 4 признаков отбраковки: nPxlMin, nPxlMax, dXYmin, dXYmax, - отведено по 3 параметра формата int: dropSpot[4*3] +0 +1 +2
  • 0 – dropSpot(nPxlMin): [ nnSpot, nnPxl, dttSpot]
  • 3 - dropSpot(nPxlMax): [ nnSpot, nnPxl, dttSpot]
  • 6 - dropSpot(dXYmin) : [ nnSpot, nnPxl, dttSpot]
  • 9 - dropSpot(dXYmax) : [ nnSpot, nnPxl, dttSpot]

Перед обращением к функции массив dropSpot (размером 12 int) должен быть обнулен.
При ldropSpot=0 статистика не ведется и массив dropSpot не требуется, то есть вместо него можно задать фиктивный параметр, например, 0.
nPxlMinминимальное число пикселов в пятне,
при lDropSpot=1: пятно отбраковывается, если число его пикселов меньше nPxlMin,
при lDropSpot=0 проверок не производится, параметр можно задать 0.
nPxlMaxмаксимальное число пикселов в пятне,
  • при lDropSpot=1: пятно отбраковывается, если число его пикселов больше nPxlMax,
  • при lDropSpot=0 проверок не производится, параметр можно задать 0.
dXYminминимальная протяженность пятна по X или по Y в пикселах,
  • при lDropSpot=1: пятно отбраковывается, если его протяженность меньше dXYMax,
  • при lDropSpot=0 проверок не производится, но параметр используется для определения шага поиска по строкам входной матрицы src (и начальной строки поиска): dI = max(1, dXYmin)
    Замечание. Задание dXYmin>1 приводит к просмотру входной матрицы src через каждые dXYmin строк, что может значительно сократить время работы функции, так как пятна меньшего размера, попавшие между строк поиска "обходятся" (однако, не гарантирует этого, например, когда пятно занимает всю матрицу). Поэтому, независимо от парамера lDropSpot надо задавать dXYmin, по возможности, большим.
dXYmaxмаксимальная протяженность пятна по X или по Y в пикселах,
  • при lDropSpot=1: пятно отбраковывается, если его протяженность больше dXYMax,
  • при lDropSpot=0 проверок не производится, параметр можно задать 0.

Ограничения: nPxlMin, nPxlMax, dXYmin, dXYmax - неотрицательные, (nPxlMin <= nPxlMax), (dXYmin <= dXYmax).
Возвращает
Функция возвращает целое число:
  • либо положительное целое, тогда это - nSpot - число найденных пятен,
  • либо отрицательное целое, тогда это - nError - код ошибки.
Число найденных пятен nSpot включает в себя также служебное и фиктивные пятна (с номерами 0,256,512,768...). Таким образом, число реальных пятен равно nSpotReal = nSpot - 1 - [nSpot/256]
Если не найдено ни одного реального пятна, то nSpot=1 – одно служебное пятно.
Код ошибки возвращается, если в начале работы функции при проверке входных данных обнаружится недопустимая комбинация параметров: тогда происходит (принудительный) выход из программы с кодом ошибки:
            dI = max(1,dXYmin);
            if ( (nHeight<=0) || (nHeight < dI +2) || (1080<nHeight) )  return -1;
            if ( (nWidth <=0) || (nWidth  < dI +2) ||((nWidth & 3)!=0)) return -2;
            if ( (dtSpot  <0) || ((dtFull != 0) && (dtFull < dtSpot)) ) return -3;
            if ( (nPxlMin <0) || (nPxlMax < nPxlMin) )  return -4;
            if ( (dXYmin  <0) || (dXYmax  < dXYmin)  )  return -5;
            if   (mSpot   <0)                   return -6;
При нормальном выходе из функции (без ошибок) в параметре Ymin служебного пятна сообщается дополнительный признак завершения программы nExitCode:
  • spot[0].Ymin=0 – вся матрица src просмотрена, найдены все пятна, естественный выход из программы.
  • spot[0].Ymin=1 – принудительный выход из программы по исчерпанию заданного времени работы программы dtFull>0.
  • spot[0].Ymin=2 – принудительный выход из программы по нахождению заданного количества пятен mSpot>0.
Заметки
Предельные случаи
Следует выделить предельные случаи:
  • одно сплошное пятно на всю матрицу - максимальное время работы функции и максимальный размер массива pixels (но минимальный размер массива spot),
  • «шахматная доска» - однопикселные пятна, расположенные по диагоналям - максимальный размер массива spot.
Алгоритм
В процессе поиска координаты всех пикселов каждого пятна сохраняются в массиве pixels:
  • пикселы каждого пятна занимают непрерывную область в массиве pixels,
  • параметр spot[i].noPxl i-го пятна в массиве spot указывает на начальный пиксел (i+1)-го пятна. В начале работы программы устанавливается указатель на начальный пиксел следующего пятна noPxl = 0.
    1. Цикл поиск пятна (осуществляется построчным попиксельным проходом матрицы src),
    если очередной пиксел нулевой, то переход к следующему пикселу
    иначе (встретился ненулевой пиксел)
    2. начало обработки (очередного) пятна:
    -   засечь время начала обработки пятна  tSpot0=clock();
    -   устанавливаются указатели начала и конца очереди пикселов пятна в массиве  pixels:  noPxl0 = noPxl1 = noPxl.
    -   пиксел в матрице src обнуляется,
    -   координаты пиксела заносятся в массив pixels, указатель noPxl1  увеличивается на 1
        3. while-цикл обработки пятна:
    -   выбирается пиксел noPxl0 из массива pixels, указатель noPxl0  увеличивается на 1
    -   просматриваются все его соседние элементы (с учетом параметра lDiag) координаты ненулевых пикселов записываются в массив pixels (с соответствующим увеличением указателя noPxl1)
    -   пикселы в матрице src обнуляются
    -   если указатели  noPxl0, noPxl1  не равны (не все пикселы пятна и их соседи просмотрены), то переход на начало while-цикла (3):
    // пятно найдено! noPxl0=noPxl1 - указывают на начальный пиксел
    //следующего пятна в массиве  pixels.
    Вычисление минимального прямоугольника (Xmin, Ymin, Xmax, Ymax), объемлющего пятно
    Если задан параметр lDropSpot=1, то проверка условий отбраковки пятна по признакам nPxlMin, nPxlMax, dXYmin, dXYmax
    если пятно отбраковано, то
    формирование записи массива dropSpot по соответствующему признаку,
    переход на поиск следующего пятна  (noPxl не изменяется).
    Меняется указатель  noPxl=noPxl1.
    Формирование параметров данного пятна в массиве spot[i] =
    (Xmin, Ymin, Xmax, Ymax, noPxl, 0, 0, 0)
            Если задан параметр вычисления угла наклона пятна (lAngleSpot=1), то
    вычисление codeAngle, lBadSpot и запись в spot[i] =
    (., ., ., ., ., codeAngle, lBadSpot, .)
    Запись dtSpot=clock()-tSpot0 в spot[i] = (., ., ., ., ., ., ., dtSpot).
    Выбор следующегл пиксела, переход на начало цикла поиска очередного пятна (1).
    4. Конец программы.