GLImageProcessing ROI (область интереса)

В настоящее время я пытаюсь размыть часть изображения. Я использую пример кода Apple здесь

Сам пример кода может размыть все изображение и отрисовать его в EAGLView, я хочу размыть только часть изображения, предоставив ROI.

Я не знаю, как обеспечить рентабельность инвестиций в функцию.

Вот код, который рисует изображение в представлении;

void drawGL(int wide, int high, float val, int mode)
{
static int prevmode = -1;
typedef void (*procfunc)(V2fT2f *, float);

typedef struct {
    procfunc func;
    procfunc degen;
} Filter;

const Filter filter[] = {
    { brightness             },
    { contrast               },
    { extrapolate, greyscale },
    { hue                    },
    { extrapolate, blur      }, // The blur could be exaggerated by downsampling to half size
};
#define NUM_FILTERS (sizeof(filter)/sizeof(filter[0]))
rt_assert(mode < NUM_FILTERS);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrthof(0, wide, 0, high, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glScalef(wide, high, 1);

glBindTexture(GL_TEXTURE_2D, Input.texID);

if (prevmode != mode)
{
    prevmode = mode;
    if (filter[mode].degen)
    {
        // Cache degenerate image, potentially a different size than the system framebuffer
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, DegenFBO);
        glViewport(0, 0, Degen.wide*Degen.s, Degen.high*Degen.t);
        // The entire framebuffer won't be written to if the image was padded to POT.
        // In this case, clearing is a performance win on TBDR systems.
        glClear(GL_COLOR_BUFFER_BIT);
        glDisable(GL_BLEND);
        filter[mode].degen(fullquad, 1.0);
        glBindFramebufferOES(GL_FRAMEBUFFER_OES, SystemFBO);
    }
}

// Render filtered image to system framebuffer
glViewport(0, 0, wide, high);
filter[mode].func(flipquad, val);
glCheckError();
}

И это функция, которая размывает изображение;

static void blur(V2fT2f *quad, float t) // t = 1
{
GLint tex;
V2fT2f tmpquad[4];
float offw = t / Input.wide;
float offh = t / Input.high;
int i;

glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);

// Three pass small blur, using rotated pattern to sample 17 texels:
//
// .\/.. 
// ./\\/ 
// \/X/\   rotated samples filter across texel corners
// /\\/. 
// ../\. 

// Pass one: center nearest sample
glVertexPointer  (2, GL_FLOAT, sizeof(V2fT2f), &quad[0].x);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &quad[0].s);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glColor4f(1.0/5, 1.0/5, 1.0/5, 1.0);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Pass two: accumulate two rotated linear samples
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
for (i = 0; i < 4; i++)
{
    tmpquad[i].x = quad[i].s + 1.5 * offw;
    tmpquad[i].y = quad[i].t + 0.5 * offh;
    tmpquad[i].s = quad[i].s - 1.5 * offw;
    tmpquad[i].t = quad[i].t - 0.5 * offh;
}
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].x);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glClientActiveTexture(GL_TEXTURE1);
glTexCoordPointer(2, GL_FLOAT, sizeof(V2fT2f), &tmpquad[0].s);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glBindTexture(GL_TEXTURE_2D, tex);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,      GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,         GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,         GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,         GL_PRIMARY_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_COLOR);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,    GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,       GL_PRIMARY_COLOR);

glColor4f(0.5, 0.5, 0.5, 2.0/5);
validateTexEnv();
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Pass three: accumulate two rotated linear samples
for (i = 0; i < 4; i++)
{
    tmpquad[i].x = quad[i].s - 0.5 * offw;
    tmpquad[i].y = quad[i].t + 1.5 * offh;
    tmpquad[i].s = quad[i].s + 0.5 * offw;
    tmpquad[i].t = quad[i].t - 1.5 * offh;
}
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

// Restore state
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glClientActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, Half.texID);
glDisable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,     GL_SRC_ALPHA);
glActiveTexture(GL_TEXTURE0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glDisable(GL_BLEND);
}

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

Спасибо.


person Sarpdoruk Tahmaz    schedule 30.01.2012    source источник


Ответы (2)


Я не большой знаток OpenGL ES, но этот код работает с целыми (не с ROI) текстурами на поверхности. Я тоже использовал этот пример.

Я думаю тебе надо:

  • снизить рентабельность инвестиций в изображение
  • создать новую текстуру с этим изображением
  • размытие новой текстуры
  • установить новую текстуру поверх исходной текстуры

Также несколько ссылок: Как реализовать рамку или размытие по Гауссу на iPhone, Размытие Эффект (эффект «Мокрый по мокрому») в приложении Paint с использованием OpenGL-ES, как сделать изображение более резким / размытым на iphone?

person Vlad Tsepelev    schedule 03.02.2012

Вы уже пробовали glScissor ()?

из спецификации GLES1.1:

glScissor определяет прямоугольник, называемый ножницей, в координатах окна. Первые два аргумента, x и y, определяют нижний левый угол поля. width и height определяют ширину и высоту поля.

Чтобы включить или отключить тест ножниц, вызовите glEnable и glDisable с аргументом GL_SCISSOR_TEST. Тест ножниц изначально отключен. Пока включен тест с ножницами, с помощью команд рисования можно изменять только пиксели, находящиеся внутри поля ножниц. Координаты окна имеют целочисленные значения в общих углах пикселей буфера кадра. glScissor (0, 0, 1, 1) позволяет изменять только нижний левый пиксель в окне, а glScissor (0, 0, 0, 0) не позволяет изменять какие-либо пиксели в окне.

Возможно, вам придется сделать 2 прохода вничью; сначала нефильтрованное изображение; второе - это отфильтрованное изображение, но нарисованное с помощью ножничного теста.

person Erik    schedule 07.02.2012
comment
Можно ли создать круглую область с помощью glScissor ()? - person Sarpdoruk Tahmaz; 08.02.2012
comment
Нет, в спецификации прямо указано, что это прямоугольник. Если вам нужны круги, вам придется использовать альфа-маски. - person Erik; 08.02.2012