Возникли проблемы с Box Blur Edges - PullRequest
0 голосов
/ 02 января 2012

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

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

Я использую код, найденный в другом сообщении -

Оптимизированные варианты с плавающей точкой Blur

Однако я просто не понимаю часть отраженных границ.

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

Код

        {// code from https://stackoverflow.com/questions/7860575/optimized-float-blur-variations

            //--------------------------------------
                int image_width ;
                int image_height ;
                int scale = 0;

                int weight = (radius * 2) + 1;

                int kernel_X = 0;
                int kernel_Y = 0;

                //--------------------------------------
                float sum = 0.0;

                int kernel_width = radius;//set both to the same to make the kernel square
                int kernel_height = radius;//set both to the same to make the kernel square


                // HORIZONTAL
                for(iy = 0; iy < image_height ;iy++)
                {
                    sum = 0.0;

                    // Process entire window for first pixel (including wrap-around edge)
                    for (kernel_X = 0; kernel_X <= kernel_width; kernel_X++)
                    {
                        if (kernel_X >= 0 && kernel_X < image_width)
                            //sum += src[iy * image_width ];
                            sum += src[iy * image_width + kernel_X];
                    }       

    //>--------------    border code does not reflect edges HELP!!
                    // Wrap  watch for left side of image & resulting black bar
                    for (kernel_X = (image_width - kernel_width); kernel_X < image_width; kernel_X++)
                    {
                        //  if (kernel_X >= 0 && kernel_X < image_width)// HORIZONTAL               width  = horizontal = X
                        //  sum += src[iy * kernel_width + image_width ];//<-------------------enter tester formula here
                        //  sum += src[iy + ix * image_width + kernel_X];//<-------------------FAIL
                        //  sum += src[iy * kernel_width + image_width ];//<-------------------streaky
                    }



                    // Store first window
                    tmp[iy * image_width] = (sum / weight );

                    for(ix = 1; ix < image_width; ix++)
                    {
                        // Subtract pixel leaving window
                        if (ix - kernel_width - 1 >= 0)
                            sum -= src[iy * image_width + ix - kernel_width - 1];

                        // Add pixel entering window
                        if (ix + kernel_width < image_width)
                            sum += src[iy * image_width + ix + kernel_width];
                        else
                            sum += src[iy * image_width + ix + kernel_width - image_width];

                        tmp[iy * image_width + ix] = (sum / weight);//just for testing
                    }
                }


                // VERTICAL
                for(ix = 0; ix < image_width; ix++)
                {
                    sum = 0.0;

                    // Process entire window for first pixel
                    for (kernel_Y = 0; kernel_Y <= kernel_height; kernel_Y++)
                    {
                        if (kernel_Y >= 0 && kernel_Y < image_height)
                            sum += tmp[kernel_Y * image_width + ix];
                    }
    //>--------------    border code does not reflect edges HELP!!
                    // Wrap  watch for top side of image & resulting black bar
                    for (kernel_Y = image_height-kernel_height; kernel_Y < kernel_height; kernel_Y++)
                    {
                        //if (kernel_Y >= 0 && kernel_Y < image_height)
                        //  sum += tmp[(iy + kernel_height - image_height) * image_width + ix];
                    }
                    for(iy=1;iy< image_height  ;iy++)
                    {
                        // Subtract pixel leaving window
                        if (iy-kernel_height-1 >= 0)
                            sum -= tmp[(iy - kernel_height-1) * image_width + ix];

                        // Add pixel entering window
                        if (iy + kernel_height < image_height)
                            sum += tmp[(iy + kernel_height) * image_width + ix];
                        else
                            sum += tmp[(iy + kernel_height - image_height) * image_width + ix];

                        dst[ (scale * image_width * image_height) + (iy * image_width + ix) ] = (sum / weight);

                    }
                }
        }

Я ценю любую помощь в этом.

Спасибо John

Отредактируйте здесь несколько ссылок на примеры изображений краев.

изображение с правильной размытостью http://img687.imageshack.us/img687/931/standardboxblur.jpg

Изображение с неправильными краями с использованием приведенного выше кода (обратите внимание на темную полосу на верхнем и левом краях, нижняя и правая тоже не совсем правильные) http://img202.imageshack.us/img202/5137/boxblurbadedges.jpg

1 Ответ

2 голосов
/ 03 января 2012

Это может быть проще, если вы поместите свою выборку в отдельную подпрограмму, которая, учитывая координаты x и y, возвращает значение пикселя. Затем вы можете выполнить некоторые проверки и зафиксировать значения x и y, чтобы они находились в диапазоне от 0 до ширины и от 0 до высоты соответственно. Тогда вы можете смело передавать отрицательные значения или значения, превышающие ширину или высоту. Это также позволяет вам более легко пробовать другие схемы, такие как отражение, привязка к цвету, экстраполяция и т. Д. Просто поменяйте местами функцию сэмплирования, которая привязывается к функции, выполняющей другие действия.

...