2015-08-24 5 views
2

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

картину того, что я имею в виду будет объяснить это лучше точно:

Images with bounding boxes

RGB-(255.0.255) является прозрачной маской и зеленые кадры представляют нужную рамку.

Я уже разобрался в верхней строке ограничивающего параллелепипеда:

int nAlloc = (128 * 128) * 4; 
    unsigned char* buf = new unsigned char[nAlloc]; 
    GetBitmapBits(hBMP, nAlloc, buf); 
    for(int i = 0; i < nAlloc; i += 4) 
    { 
     if(buf[i] == 255 && buf[i + 1] == 0 && buf[i + 2] == 255) 
     { 
      continue; 
     } 
     // If I hit a first non-transparent pixel, 
     // I can then calculate the row where is that pixel located. 
     else if(set_pixel == false) 
     { 
      set_pixel = true; 
      index = ceil((float)(i/4.0/128.0)); 
     } 
     ... // Converting non-transparent pixels to Black&White 
    } 

    //I'm then drawing the bitmap to window like so: 
    TransparentBlt(hdc, 5, 305 - index, 128, 128, hDC, 0, 0, 128, 128, RGB(255, 0, 255)); 

Я думаю, я знаю, как определить последнюю строку, как хорошо, но я не уверен, с этим и не имеют ни малейшего представления как узнать стороны ограничительной рамки.

+0

Возможно, вы можете использовать алгоритм [flood fill] (https://www.wikiwand.com/en/Flood_fill#/The_algorithm) (эта проблема является видом обратной заливки заливки). –

+0

@JonathanPotter Это не дает мне ограничительных линий, не так ли? Я не хочу влиять на какие-либо пиксели, я просто хочу получить боксерский ящик. Это слишком сложно для этой проблемы, я считаю. – ProXicT

+0

На самом деле вы не наполнили бы, но рекурсивный алгоритм позволит вам найти края объекта. –

ответ

4

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

RECT BoundingBox = { 0,0,0,0 }; 
const int nAlloc = (128 * 128) * 4; 
unsigned char* buf = new unsigned char[nAlloc]; 
GetBitmapBits(hBMP, nAlloc, buf); 

bool found; 

//search upper bound 
found = false; 
for (int row = 0; row<128 && !found; row++) //row 
{ 
    for (int col = 0; col<128 && !found; col++) //column 
    { 
     int idx = (row * 128 + col) * 4; 
     if (!(buf[idx] == 255 && buf[idx + 1] == 0 && buf[idx + 2] == 255)) //not transparent 
     { 
      BoundingBox.top = row; 
      found = true; 
     } 
    } 
} 

//search lower bound 
found = false; 
for (int row = 127; row >= 0 && !found; row--) //row 
{ 
    for (int col = 127; col >= 0 && !found; col--) //column 
    { 
     int idx = (row * 128 + col) * 4; 
     if (!(buf[idx] == 255 && buf[idx + 1] == 0 && buf[idx + 2] == 255)) //not transparent   { 
      BoundingBox.bottom = row; 
      found = true; 
     } 
    } 
} 


//search left bound 
found = false; 
for (int col = 0; col<128 && !found; col++) //row 
{ 
    for (int row = 0; row<128 && !found; row++) //column 
    { 
     int idx = (row * 128 + col) * 4; 
     if (!(buf[idx] == 255 && buf[idx + 1] == 0 && buf[idx + 2] == 255)) //not transparent   { 
      BoundingBox.left = col; 
      found = true; 
     } 
    } 
} 


//search right bound 
found = false; 
for (int col = 127; col >= 0 && !found; col--) //row 
{ 
    for (int row = 127; row >= 0 && !found; row--) //column 
    { 
     int idx = (row * 128 + col) * 4; 
     if (!(buf[idx] == 255 && buf[idx + 1] == 0 && buf[idx + 2] == 255)) //not transparent   { 
      BoundingBox.right = col; 
      found = true; 
     } 
    } 
} 

//now the variable "BoundingBox" contains your BoundingBox 

Надеюсь, мой ответ вам поможет.

+0

Это хорошо, но на самом деле это не решает мою проблему. Мне тоже нужно найти стороны. Не только верх и низ, которые у меня уже есть, как я упоминал в своем вопросе. – ProXicT

+0

Но есть и стороны в этом коде, если вы прокрутите вниз – Philinator

+0

О, мне так глупо сейчас, огромное спасибо! – ProXicT

1

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

const int rowcnt = 128; 
const int colcnt = 128; 
const int bytesperpix = 4; 
int pos = 0; 
int colmin = colcnt; 
int colmax = 0; 
int colpos = 0; 
for(int r = 0; r < rowcnt; ++r) 
{ 
    for(int c = 0; c < colcnt * bytesperpix; c += 4) 
    { 
     pos = r * colcnt * bytesperpix + c; 
     if(buf[pos] == 255 && buf[pos + 1] == 0 && buf[pos + 2] == 255) 
     { 
      continue; 
     } 
     else 
     { 
      colpos = c/bytesperpix; 
      if(colpos < colmin) 
       colmin = colpos; 
      else if(colpos > colmax) 
       colmax = colpos; 
     } 
    } 
} 
+0

Я думаю, что это не сработает. Растровое изображение имеет 4 байта только в одном dimensoin. Поэтому, когда вы повторяете в столбце, это должно быть всего лишь от 0 до 127. Когда я пробовал код раньше, не глядя дальше, он всегда попадает во второй оператор if. – ProXicT

+0

Я пересмотрел код. теперь он выполняет итерации строк от 0 до 128 и столбцов от 0 до 512. –

+0

Он по-прежнему выполняет второе условие. После этого цикла colmax равен значению 65532. – ProXicT

Смежные вопросы