|
|
Регистрация | << Правила форума >> | FAQ | Пользователи | Календарь | Поиск | Сообщения за сегодня | Все разделы прочитаны |
|
Опции темы | Поиск в этой теме | Опции просмотра |
#1
|
|||
|
|||
Алгоритм Magic Wang (выделение пикселей похожих)
Доброго всем времени суток!
Коллеги, знает ли кто нибудь каким образом реализован алгоритм Magic Wang в графических редакторах (фотошоп, корел). интересует сам алгоритм, что там сравнивается и каким образом. Пробовал переводить картинку в HSB и выделять по брайтнессу но все равно выходит далеко не так как в редакторах, пришел к выводу что скорее всего там сравнивается не пиксель за пикселем в рекурсии как пытался сделать я, а скорее всего какая-то область типа квадратика 3х3 или больше. и возможно какаято средняя яркость там считается. В общем если кто сталкивался с подобной задачей подскажите как именно реализуется такой алгоритм. Гугул перегулил весь, нашел много интересного но именно по этой теме ничего |
#2
|
||||
|
||||
Цитата:
Код:
type TFillItem = class(TObject) // Untested coordinates that will be added to a list. Xfill, Yfill : Word; end; function CreateHRGN(Bitmap : TBitmap; X, Y : Word; RGN : HRGN) : HRGN; var FillList : TList; // The untested list of coordinates. function TColorToRGBTriple(Color : TColor) : TRGBTriple; type TRGBQuad = packed record case integer of 0 : (Color : TColor); 1 : (r, g, b, a : byte); end; var RGBQuad : TRGBQuad; begin RGBQuad.Color:= Color; Result.rgbtRed:= RGBQuad.r; Result.rgbtGreen:= RGBQuad.g; Result.rgbtBlue:= RGBQuad.b; end; {TColorToRGBTriple} function RGBTripleToTColor(RGBTriple : TRGBTriple) : TColor; begin Result:= RGBTriple.rgbtBlue shl 16 + RGBTriple.rgbtGreen shl 8 + RGBTriple.rgbtRed; end; {RGBTripleToTColor} procedure FillBitmap(Bitmap : TBitmap; X, Y : integer; Depth : Word); type TRGBArray = array[0..0] of TRGBTriple; pRGBArray = ^TRGBArray; var pc: pRGBArray; RGNTemp : HRGN; FillItem : TFillItem; begin {$ifopt R+} {$define RangeCheck} {$endif} {$R-} if (X>= 0) and (X < Bitmap.Width) and (Y>= 0) and (Y < Bitmap.Height) then begin pc:= Bitmap.Scanline[Y]; if (RGBTripleToTColor(pc[X]) <>clBlack) and (RGBTripleToTColor(pc[X]) <>clNavy) then begin if (Depth>10000) then begin // Recursive depth exceeded ... so pack up FillItem:= TFillItem.Create; // all our pending test coordinates and FillItem.Xfill:= X; // leave. FillItem.Yfill:= Y; FillList.Add(FillItem); end else begin if (RGN = 0) then // No region - must be new ... RGN:= CreateRectRgn(X, Y, X+1, Y+1) // so make one ... else begin // otherwise combine it with RGNTemp:= CreateRectRgn(X, Y, X+1, Y+1); // this new selection. CombineRgn(RGN, RGN, RGNTemp, RGN_XOR); DeleteObject(RGNTemp); // Must remember to get rid of unwanted regions. end; {if} pc[X]:= TColorToRGBTriple(clNavy); // Leave a marker to say we've been here. FillBitmap(Bitmap, X-1, Y, Depth+1); // Left ... FillBitmap(Bitmap, X+1, Y, Depth+1); // Right ... FillBitmap(Bitmap, X, Y-1, Depth+1); // Up ... FillBitmap(Bitmap, X, Y+1, Depth+1); // Down ... end; {if} end; {if} end; {if} {$ifdef RangeCheck} {$R+} {$undef RangeCheck} {$endif} end; {FillBitmap} var Depth : Word; begin Bitmap.PixelFormat:= pf24bit; // Need 24 bit... Depth:= 0; // Not started tree search ... so zero depth. FillList:= TList.Create; // Create our fill list. FillBitmap(Bitmap, X, Y, Depth); // Go and fill... while (FillList.Count>0) do begin // Hmm ... too many recursive levels ... with TFillItem(FillList[pred(FillList.Count)]) do begin // ... step through all the pending X:= Xfill; // coordinates. Y:= Yfill; Free; // Delete these coordinates, we're about to do them. end; {with} FillList.Delete(pred(FillList.Count)); // Delete this entry from the list too. Depth:= 0; FillBitmap(Bitmap, X, Y, Depth); // Go and fill again ... end; {while} // Keep on until the list's empty. FillList.Free; // Free the list ... we're done. Result:= RGN; // Return the region. end; Я не понял Вашего вопроса, но всё же Вам на него отвечу! |
#3
|
|||
|
|||
помоему это просто реализация алгоритма перебора областей и т.д. пример рекурсивной функции, это я и сам могу
НО в этом коде нет того о чем я спрашивал, а именно, как сравниваются похожие пиксели, везде где я видел употребляется словосочетание HSB Tolerance т.е. подобные пиксели |
#4
|
||||
|
||||
Там вроде тупо по цвету(оттенку) сравнение идет в задаваемом процентном соотношении, сегодня на работе попробую накатать примерчик, вечером скину.
|
#5
|
|||
|
|||
вот еще прикол ну тут мое понимание вообще кончилось может кто пояснит в чем прикол посмотрите на условие и значение переменных и где курсор находиться т.е. компилятор проигнорил условие или я уже переработался и реально чето не понял
|
#6
|
||||
|
||||
Цитата:
|
Этот пользователь сказал Спасибо poli-smen за это полезное сообщение: | ||
TeRomani (17.05.2013)
|
#7
|
|||
|
|||
Цитата:
Да я так пробовал)) и по всем трем, и отдельно по каждой))) все-таки мне кажется что там не отдельные пиксели сравнивают а группы по 9 или как то еще |
#8
|
||||
|
||||
Сорри, что задержался, выходные забористые вышли!
Если еще актуально, лови может быть тебе подойдет! Алгоритм лохматый, неотесанный, т.е. можно оптимизировать в разы. Основная процедура SelectedReg(рекурсия) З.Ы. выделенная область инвертируется |
#9
|
||||
|
||||
Цитата:
А Stack Overflow не может возникнуть? — Как тебя понимать? — Понимать меня не обязательно. Обязательно меня любить и кормить вовремя. На Delphi, увы, больше не программирую. Рекомендуемая литература по программированию Последний раз редактировалось M.A.D.M.A.N., 22.05.2013 в 14:51. |
#10
|
||||
|
||||
Цитата:
он меня заколебал Пока в настройках компилятора размер стека не увеличил. Вообще странно, писал прогу дя постраения фракталов, там у меня в процедуре было куева туча локаьных переменных, да и параметры я передовал нифига не через указатели, хоть бы заикнулся. А здесь процедурка небольшая а жрет трындец, даже не знаю в каком моменте . При среднем изображении вроде нормально работает на больших не проверял Последний раз редактировалось Pilot_Red, 22.05.2013 в 21:27. |