внедрить лапласиан 3х3 - PullRequest
       23

внедрить лапласиан 3х3

7 голосов
/ 16 сентября 2011

Я читаю DIP 2-е издание Гонсалеса и Вудса и пытаюсь испачкать руки лапласовой маской (стр. 129 и 130) с помощью wxImage.

float kernel [3][3]= {{1, 1, 1},{1,-8, 1},{1, 1, 1}};   

Вот циклы обработки:

unsigned char r,g,b;                    

float rtotal, gtotal, btotal; rtotal = gtotal = btotal = 0.0;   
//ignore the border pixel              

for(int i = 1; i<imgWidth-1; i++)
{

   for(int j = 1; j<imgHeight-1; j++) 
    {

     rtotal = gtotal=btotal =0.0;


       for(int y = -1; y<=1;y++)

       {

            for(int x = -1; x<=1;x++)

            {

            // get each channel pixel value

            r = Image->GetRed(i+y,j+x);

            g = Image->GetGreen(i+y,j+x);

            b = Image->GetBlue(i+y,j+x);

            // calculate each channel surrouding neighbour pixel value base   

            rtotal += r* kernel[y+1][x+1];

            gtotal += g* kernel[y+1][x+1] ;

            btotal += b* kernel[y+1][x+1];

            }

    }
            //edit1: here is how to sharpen the image
            // original pixel - (0.2 * the sum of pixel neighbour)
            rtotal = loadedImage->GetRed(x,y) - 0.2*rtotal;

    gtotal = loadedImage->GetGreen(x,y) - 0.2*gtotal;

    btotal = loadedImage->GetBlue(x,y) - 0.2*btotal;
    // range checking

    if (rtotal >255) rtotal = 255;

       else if (rtotal <0) rtotal = 0;

    if(btotal>255) btotal = 255;

       else if(btotal < 0) btotal = 0;

    if(gtotal > 255) gtotal = 255;

       else if (gtotal < 0 ) gtotal =0;

    // commit new pixel value

    Image->SetRGB(i,j, rtotal, gtotal, btotal);

Я применил это к изображению Северного полюса (серое изображение), и все, что я получил, - это капля черно-белых пикселей!

Есть идеи, где я мог что-то пропустить в циклах for?

Edit1: наконец получить ответ после просмотра в Google.Этот материал DSP определенно хитрый!Я добавил к коду выше, это будет резкость изображения.

Ура

Ответы [ 3 ]

5 голосов
/ 17 сентября 2011

Во-первых, результат свертывания с лапласианом может иметь отрицательные значения. Рассмотрим пиксель со значением 1, окруженный нулями. Результат свертки в этом пикселе будет -8.

Во-вторых, диапазон результата будет между [-8 * 255, 8 * 255], который определенно не умещается в 8 бит. По сути, когда вы выполняете проверку диапазона, вы теряете большую часть информации, и большинство ваших результирующих пикселей будет иметь значение 0 или 255.

То, что вам нужно сделать, это сохранить результат в массиве типа со знаком и достаточно широким, чтобы обработать диапазон. Затем, если вы хотите вывести 8-битное изображение, вам нужно будет изменить масштаб значений так, чтобы -8 * 255 соответствовал 0, а 8 * 255 соответствовал 255. Или вы можете изменить его масштаб так, чтобы наименьшее значение соответствовало 0 и наибольшее значение отображается на 255.

Редактировать: в данном конкретном случае вы можете сделать следующее:

rtotal = (rtotal + 8 * 255) / (16 * 255) * 255;

, что упрощается до

rtotal = (rtotal + 8 * 255) / 16;

Это отобразит rtotal в диапазоне от 0 до 255 без усечения. Вы должны сделать то же самое для gtotal и btotal.

2 голосов
/ 17 сентября 2011

Я думаю, что ваша проблема в том, что r, g и b имеют тип unsigned int и что в зависимости от того, какой компилятор вы используете и как он оптимизируется, вы неявно приводите их к плавающим в строках rtotal += r* kernel[y+1][x+1]; и т. Д.если компилятор приведёт к вашим ожиданиям иначе, вычисление среднего значения не будет работать, потому что unsigned int не может быть отрицательным.

Решение: замените r, g и b на float.

Победане имеет значения, но есть небольшая ошибка в строках r = Image->GetRed(i+y,j+x);, потому что я зацикливаюсь по горизонтали, а j зацикливается по вертикали.

1 голос
/ 16 сентября 2011

Разве вы не должны делить на количество пикселей в маске после вычисления взвешенной суммы, получая, таким образом, взвешенное среднее? Без этого сумма значений в девять пикселей (даже при умножении на не слишком яркие значения маски) легко превысит 255.

...