c++ - Sobel Edge Detection without a buffer -


for embedded design attempting implement sobel's edge detection on board without use of buffer. i.e. reading , writing directly screen. can however, store 1 or 2 imge width full of data referenced later. due limitations set forth board. have fallen issue. recieve noise regardless if attempt sobel or edge detection algorithm. code below, have suggestions

version 1

void sobeledgedetection2() {     int gx[3][3];     int gy[3][3];      int sumx[3];     int sumy[3];     int sum[3];     int pix = 0;     int piy = 0;     //uint8_t r, g, b = 0;     int i, j = 0;      //unpackedcolour pixval;     uint16_t *buffer;     // allocate space scan lines , odd scan lines     buffer = new uint16_t[_gl->getwidth()];     //buffer previous line     uint16_t *buft;     // allocate space scan lines , odd scan lines     buft = new uint16_t[_gl->getwidth()];      // masks //////////////////////////////////////     //x//     gx[0][0] = -1;     gx[0][1] = 0;     gx[0][2] = 1;     gx[1][0] = -2;     gx[1][1] = 0;     gx[1][2] = 2;     gx[2][0] = -1;     gx[2][1] = 0;     gx[2][2] = 1;     //y//     gy[0][0] = 1;     gy[0][1] = 2;     gy[0][2] = 1;     gy[1][0] = 0;     gy[1][1] = 0;     gy[1][2] = 0;     gy[2][0] = -1;     gy[2][1] = -2;     gy[2][2] = -1;      (int y = 0; y < _gl->getheight(); y++) {         (int x = 0; x < _gl->getwidth(); x++) {             sumx[0] = sumx[1] = sumx[2] = 0;             sumy[0] = sumy[1] = sumy[2] = 0;              if (y == 0 || y == _gl->getheight() - 1) {                 sum[0] = sum[1] = sum[2] = 0;             } else if (x == 0 || x == _gl->getwidth() - 1) {                 sum[0] = sum[1] = sum[2] = 0;             } else {                 (i = -1; <= 1; i++) {                     (j = -1; j <= 1; j++) {                         pix = j + x;                         piy = + y;                          pixel16 pix = getpixel(pix, piy);                         uint8_t red = pix.red;                         uint8_t green = pix.green;                         uint8_t blue = pix.blue;                          sumx[0] += (red) * gx[j + 1][i + 1];                         sumx[1] += (green) * gx[j + 1][i + 1];                         sumx[2] += (blue) * gx[j + 1][i + 1];                          sumy[0] += (red) * gy[j + 1][i + 1];                         sumy[1] += (green) * gy[j + 1][i + 1];                         sumy[2] += (blue) * gy[j + 1][i + 1];                     }                 }                  sum[0] = abs(sumx[0]) + abs(sumy[0]);                 sum[1] = abs(sumx[1]) + abs(sumy[1]);                 sum[2] = abs(sumx[2]) + abs(sumy[2]);             }             if (sum[0] > 255)                 sum[0] = 255;             if (sum[0] < 0)                 sum[0] = 0;              if (sum[1] > 255)                 sum[1] = 255;             if (sum[1] < 0)                 sum[1] = 0;              if (sum[2] > 255)                 sum[2] = 255;             if (sum[2] < 0)                 sum[2] = 0;              int newpixel[3];             newpixel[0] = (255 - ((unsigned char) (sum[0])));             newpixel[1] = (255 - ((unsigned char) (sum[1])));             newpixel[2] = (255 - ((unsigned char) (sum[2])));              pixel16 pix(newpixel[0], newpixel[1], newpixel[2]);             buffer[x] = packcolour(pix).packed565;         }         //need move cursor         // draw         this->paintrow(point(0, y), buffer, _gl->getwidth());     }     delete[] buffer; } 

version2

/**      * https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/image-processing/edge_detection.html      * 1 iterate on every pixel in image      * 2 apply x gradient kernel      * 3 apply y gradient kernel      * 4 find length of gradient using pythagoras' theorem      * 5 normalise gradient length range 0-255      * 6 set pixels new values      */     void sobeledgedetection4() {         unpackedcolour colour;         (int x = 1; x < _gl->getwidth() - 1; x++) {             (int y = 1; y < _gl->getheight() - 1; y++) {                 // initialise gx , gy 0                 int gx = 0;                 int gy = 0;                 unsigned int intensity = 0;                  // left column                 pixel16 pixel = this->getpixel(x - 1, y - 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += -intensity;                 gy += -intensity;                  pixel = this->getpixel(x - 1, y);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += -2 * intensity;                  pixel = this->getpixel(x - 1, y + 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += -intensity;                 gy += +intensity;                  // middle column                 pixel = this->getpixel(x, y - 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gy += -2 * intensity;                  pixel = this->getpixel(x, y + 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gy += +2 * intensity;                  // right column                 pixel = this->getpixel(x + 1, y - 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += +intensity;                 gy += -intensity;                  pixel = this->getpixel(x + 1, y);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += +2 * intensity;                  pixel = this->getpixel(x + 1, y + 1);                 intensity = pixel.red + pixel.green + pixel.blue;                 gx += +intensity;                 gy += +intensity;                  // calculate gradient length                 unsigned int length = (unsigned int) sqrt(                         (float) (gx * gx) + (float) (gy * gy));                  // normalise length 0 255                 length = length / 17;                  // draw pixel on edge image                 pixel16 pixel2(length,length,length);                 this->setpixel(x, y, pixel2);             }         }     } 

version 3

// sobel map x axis     const double _sobel_gx[3][3] = { { -1.0, +0.0, +1.0 }, { -2.0, +0.0, +2.0 },             { -1.0, +0.0, +1.0 } };     // sobel map y axis     const double _sobel_gy[3][3] = { { +1.0, +2.0, +1.0 }, { +0.0, +0.0, +0.0 },             { -1.0, -2.0, -1.0 } }; double get_sobel_gradient(int width, int height, int x, int y) {         double sobel_gradient_x = 0, sobel_gradient_y = 0;         int mx = 0, = 0, sx = 0, sy = 0;          (mx = x; mx < x + 3; mx++) {             sy = 0;             (my = y; < y + 3; my++) {                 if (mx < width && < height) {                     //int r, g, b, idx;                     int idx = (mx + width * my) * 3;                      pixel16 pixval = this->getpixel(idx);                      //r = pixval.red;                     //g = pixval.green;                     //b = pixval.blue;                     unpackedcolour col = this->packcolour(pixval);                     sobel_gradient_x += col.packed565 * _sobel_gx[sx][sy];                     sobel_gradient_y += col.packed565 * _sobel_gy[sx][sy];                 }                 sy++;             }             sx++;         }          return abs(sobel_gradient_x) + abs(sobel_gradient_y);     }      void sobeledgedetection3() {         double threshold = 50000.0;         unpackedcolour colour;         (int y = 0; y < _gl->getheight(); y++) {             (int x = 0; x < _gl->getwidth(); x++) {                 if (get_sobel_gradient(_gl->getwidth(), _gl->getheight(), x, y)                         >= threshold) {                     colour.packed565 = 0x0000;          //set white                 } else {                     colour.packed565 = 0xffff;          //set black                 }                 this->setpixel(x, y, colour);             }         }     } 

for version 1, after allocate 2 buffers (just use buffer , buft), create 2 pointers point current , previous rows, this:

uint16_t *currentrow = buffer; uint16_t *prevrow = buft; 

inside row loop, write currentrow instead of buffer:

pixel16 pix(newpixel[0], newpixel[1], newpixel[2]); currentrow[x] = packcolour(pix).packed565; 

because sobel filter reads previous row, can't overwrite row until after have finished calculating filtered values row after it. @ end of loop, calling paintrow(), draw previous row (if 1 exists), , swap buffers current becomes previous, , previous becomes new current row (to overwritten on next pass through loop). on last row current row drawn, because otherwise won't since outer loop terminate.

if(y > 0) // draw previous row if not first row:     this->paintrow(point(0, y-1), prevrow, _gl->getwidth()); if(y == _gl->getheight()-1) // draw current row if last:     this->paintrow(point(0, y), currentrow, _gl->getwidth()); // swap row pointers: uint16_t *temp = prevrow; prevrow = currentrow; currentrow = temp; 

the same strategy should work other versions.


Comments

Popular posts from this blog

IF statement in MySQL trigger -

c++ - What does MSC in "// appease MSC" comments mean? -

javascript - Blogger related post gadget image Resize s72-c [ Need Expert Help ] -