Changing the value of a pixel during averaging??

asked 2018-02-15 02:32:39 -0600

imp3ga gravatar image

updated 2018-02-15 03:15:09 -0600

I am trying to detect clouds in a video so they can be ignored during feature detection and tracking but without ignoring man-made features like bridges and signs. I thought about looking at texture energy and found this piece of code online, which seems to reference texture energy ("e5l5"). There is a part where the average intensity is taken in a 5x5 pixel neighbourhood, but the value of the middle pixel is changed DURING the averaging, which then affects the rest of the averaging, resulting in these cascading patterns. This seems like a mistake to me, but the resulting images seem to do a pretty good job at separating bridges, lampposts, signs, trees etc from the clouds and the sky. Is there some other reason why this works, if so can somebody point me in the right direction? Or is it a mistake and a coincidence that it works? I also don't understand why it still works if using a 3 channel image, even though that means the averaging is going across 5 channels (eg R,G,B, then an R and G from the next pixel). What am I missing?

The code is :

#include <iostream>
#include <opencv2/highgui/highgui.hpp>

using namespace cv;
using namespace std;

int main()
{
int  sum1;

Mat img=imread("/home/jeenal/Pictures/testeagle.jpg",CV_LOAD_IMAGE_UNCHANGED);
if(img.empty())
{
 cout<<"No image";
 return -1;
}

int rows=img.rows;
int columns=img.cols;

int l5[5]={1,4,6,4,1};
int e5[5]={-1,-2,0,2,1};
int e5l5[5][5]={0};

for(int i=0;i<5;i++)
   for(int j=0;j<5;j++)
       e5l5[i][j]=e5[i]*l5[j];


int win[5][5]={0};
int win1[5][5]={0};

for (int i=2;i<(rows-2);i++)
    for (int j=2;j<(columns-2);j++)
        {
          sum1=0;
          for (int x=-2;x<=2;x++)
            for (int y=-2;y<=2;y++)
                win[x+2][y+2]=img.at<uchar>(i+x,j+y);
           for(int k1=0;k1<5;k1++)
              for(int k2=0;k2<5;k2++)
                 {
                  for(int k3=0;k3<5;k3++)
                     win1[k1][k2]+=win[k1][k3] * e5l5[k3][k2] ;
                  sum1+=abs(win1[k1][k2]);
                  win1[k1][k2]=0;
                  }  
           if(sum1/25>255)
              img.at<uchar>(i,j)=255;                
           else img.at<uchar>(i,j)=sum1/(5*5);

        }

namedWindow("texture features",CV_WINDOW_AUTOSIZE);
imshow("texture features",img);
waitKey(0);
return 0;
}

Thanks

edit retag flag offensive close merge delete

Comments

1

i'd say, that code is crap, and your observation is correct. it won't work with 3-channel images, and you can't apply a convolution like that in-place. try with a grayscale (single channel) image, and use a seperate

 Mat out(img.size(), img.type());
 ...
 out.at<uchar>(i,j)=something;
berak gravatar imageberak ( 2018-02-15 05:34:54 -0600 )edit