Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Graphics
  4. Bitmap blur problem [modified]

Bitmap blur problem [modified]

Scheduled Pinned Locked Moved Graphics
helpgraphicsdata-structures
32 Posts 3 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • N Offline
    N Offline
    Naturality
    wrote on last edited by
    #1

    Hi, I have a program that is supposed to blur bitmaps in a Gaussian type fashion. However, all this does is change the light greys to a yellow-ey colour. Here is some code: Functions:

    void set_pixel(int x,int y, RGBTRIPLE colour){
    image[(bmp.biHeight-1-y)*bmp.biWidth+x] = colour;
    }

    void get_pixel(int x, int y, RGBTRIPLE colour){
    colour = image[(bmp.biHeight-1-y)*bmp.biWidth+x];
    }

    void avg(RGBTRIPLE colour[], RGBTRIPLE merge, int size) {
    for(int i=0; i merge.rgbtBlue += colour[i].rgbtBlue;
    merge.rgbtGreen += colour[i].rgbtGreen;
    merge.rgbtRed += colour[i].rgbtRed;
    }
    merge.rgbtBlue = merge.rgbtBlue / size;
    merge.rgbtGreen= merge.rgbtGreen / size;
    merge.rgbtRed = merge.rgbtRed / size;
    }

    Implementation:

    for(int y = 0; y < bmp.biHeight; y=y+3){
    for(int x = 0; x for(int i = 0; i < 9; i++){
    int yp=0, xp=0;
    get_pixel(x+xp,y+yp,blank[i]); // blank is an RGBTRIPLE array
    if(xp<3)
    xp++;
    else{
    xp = 0;
    yp++;
    }
    }
    avg(blank, Merge, 9);
    set_pixel(x,y,Merge);
    }}

    Any help you can give would be much appreciated. Thanks :)

    modified on Saturday, June 7, 2008 9:35 PM

    C T 2 Replies Last reply
    0
    • N Naturality

      Hi, I have a program that is supposed to blur bitmaps in a Gaussian type fashion. However, all this does is change the light greys to a yellow-ey colour. Here is some code: Functions:

      void set_pixel(int x,int y, RGBTRIPLE colour){
      image[(bmp.biHeight-1-y)*bmp.biWidth+x] = colour;
      }

      void get_pixel(int x, int y, RGBTRIPLE colour){
      colour = image[(bmp.biHeight-1-y)*bmp.biWidth+x];
      }

      void avg(RGBTRIPLE colour[], RGBTRIPLE merge, int size) {
      for(int i=0; i merge.rgbtBlue += colour[i].rgbtBlue;
      merge.rgbtGreen += colour[i].rgbtGreen;
      merge.rgbtRed += colour[i].rgbtRed;
      }
      merge.rgbtBlue = merge.rgbtBlue / size;
      merge.rgbtGreen= merge.rgbtGreen / size;
      merge.rgbtRed = merge.rgbtRed / size;
      }

      Implementation:

      for(int y = 0; y < bmp.biHeight; y=y+3){
      for(int x = 0; x for(int i = 0; i < 9; i++){
      int yp=0, xp=0;
      get_pixel(x+xp,y+yp,blank[i]); // blank is an RGBTRIPLE array
      if(xp<3)
      xp++;
      else{
      xp = 0;
      yp++;
      }
      }
      avg(blank, Merge, 9);
      set_pixel(x,y,Merge);
      }}

      Any help you can give would be much appreciated. Thanks :)

      modified on Saturday, June 7, 2008 9:35 PM

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      looks messy. My image processing articles here on code project have a Gaussian blur in them.

      Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )

      1 Reply Last reply
      0
      • N Naturality

        Hi, I have a program that is supposed to blur bitmaps in a Gaussian type fashion. However, all this does is change the light greys to a yellow-ey colour. Here is some code: Functions:

        void set_pixel(int x,int y, RGBTRIPLE colour){
        image[(bmp.biHeight-1-y)*bmp.biWidth+x] = colour;
        }

        void get_pixel(int x, int y, RGBTRIPLE colour){
        colour = image[(bmp.biHeight-1-y)*bmp.biWidth+x];
        }

        void avg(RGBTRIPLE colour[], RGBTRIPLE merge, int size) {
        for(int i=0; i merge.rgbtBlue += colour[i].rgbtBlue;
        merge.rgbtGreen += colour[i].rgbtGreen;
        merge.rgbtRed += colour[i].rgbtRed;
        }
        merge.rgbtBlue = merge.rgbtBlue / size;
        merge.rgbtGreen= merge.rgbtGreen / size;
        merge.rgbtRed = merge.rgbtRed / size;
        }

        Implementation:

        for(int y = 0; y < bmp.biHeight; y=y+3){
        for(int x = 0; x for(int i = 0; i < 9; i++){
        int yp=0, xp=0;
        get_pixel(x+xp,y+yp,blank[i]); // blank is an RGBTRIPLE array
        if(xp<3)
        xp++;
        else{
        xp = 0;
        yp++;
        }
        }
        avg(blank, Merge, 9);
        set_pixel(x,y,Merge);
        }}

        Any help you can give would be much appreciated. Thanks :)

        modified on Saturday, June 7, 2008 9:35 PM

        T Offline
        T Offline
        Tim Craig
        wrote on last edited by
        #3

        You seem to have had a problem when pasting your code but unless it didn't make it, I don't see where Merge gets zeroed out between calls to avg().

        If you don't have the data, you're just another asshole with an opinion.

        N 1 Reply Last reply
        0
        • T Tim Craig

          You seem to have had a problem when pasting your code but unless it didn't make it, I don't see where Merge gets zeroed out between calls to avg().

          If you don't have the data, you're just another asshole with an opinion.

          N Offline
          N Offline
          Naturality
          wrote on last edited by
          #4

          I hadn't put the zeroing of Merge in :S, thanks for pointing that out. However, this still doesn't solve the problem. I have also tried zeroing blank between calls of avg(). This didn't help either. and Christian, I'm checking out your tutorials now, unfortunately I will have to translate them into C++ but I hope it will help. EDIT: Aha! I have just done something I realised I should have done before. I tried to create random colours for each pixel, in a noise type function without writing before blurring. I have set these up into 2 seperate projects and now the ouput is a grey screen with some black dots going in lines across the screen :S Here's a picture of what the output is: http://s131.photobucket.com/albums/p287/CorporateRock/blurtry.jpg[^]

          "Sir, I protest. I am NOT a merry man!"

          modified on Sunday, June 8, 2008 8:52 AM

          T 1 Reply Last reply
          0
          • N Naturality

            I hadn't put the zeroing of Merge in :S, thanks for pointing that out. However, this still doesn't solve the problem. I have also tried zeroing blank between calls of avg(). This didn't help either. and Christian, I'm checking out your tutorials now, unfortunately I will have to translate them into C++ but I hope it will help. EDIT: Aha! I have just done something I realised I should have done before. I tried to create random colours for each pixel, in a noise type function without writing before blurring. I have set these up into 2 seperate projects and now the ouput is a grey screen with some black dots going in lines across the screen :S Here's a picture of what the output is: http://s131.photobucket.com/albums/p287/CorporateRock/blurtry.jpg[^]

            "Sir, I protest. I am NOT a merry man!"

            modified on Sunday, June 8, 2008 8:52 AM

            T Offline
            T Offline
            Tim Craig
            wrote on last edited by
            #5

            Ah, I think I see it now. In avg(), Merge is of type RGBTRIPLE. Each color element is an unsigned char which limits its value to 0 to 255. You're adding nine elements into each color value before you take the average. On average, you've overflowed it after the second addition and wrapped around. You need to use a temporary accumulator that's at least an unsigned short but hey, go wild and make it an unsigned int. :laugh: Then you're covered if you use a bigger kernel than 3x3.

            If you don't have the data, you're just another asshole with an opinion.

            N 1 Reply Last reply
            0
            • T Tim Craig

              Ah, I think I see it now. In avg(), Merge is of type RGBTRIPLE. Each color element is an unsigned char which limits its value to 0 to 255. You're adding nine elements into each color value before you take the average. On average, you've overflowed it after the second addition and wrapped around. You need to use a temporary accumulator that's at least an unsigned short but hey, go wild and make it an unsigned int. :laugh: Then you're covered if you use a bigger kernel than 3x3.

              If you don't have the data, you're just another asshole with an opinion.

              N Offline
              N Offline
              Naturality
              wrote on last edited by
              #6

              Thanks for the advice :D. I used an unsigned int for red green and blue. This still didn't solve the problem, however as it still seems too organised and is tritone. :S Sorry my code is so messed up.

              "Sir, I protest. I am NOT a merry man!"

              T 1 Reply Last reply
              0
              • N Naturality

                Thanks for the advice :D. I used an unsigned int for red green and blue. This still didn't solve the problem, however as it still seems too organised and is tritone. :S Sorry my code is so messed up.

                "Sir, I protest. I am NOT a merry man!"

                T Offline
                T Offline
                Tim Craig
                wrote on last edited by
                #7

                Try giving us the latest version. Kind of hard to guess how you've rattled the box. :)

                If you don't have the data, you're just another asshole with an opinion.

                N 1 Reply Last reply
                0
                • T Tim Craig

                  Try giving us the latest version. Kind of hard to guess how you've rattled the box. :)

                  If you don't have the data, you're just another asshole with an opinion.

                  N Offline
                  N Offline
                  Naturality
                  wrote on last edited by
                  #8

                  Okay, here's the full file(sans the reading/writing stuff)

                  void set_pixel(long x,long y, RGBTRIPLE colour){
                  image[(bmp.biHeight-1-y)*bmp.biWidth+x] = colour;
                  }

                  void get_pixel(int x, int y, RGBTRIPLE colour){
                  colour = image[(bmp.biHeight-1-y)*bmp.biWidth+x];
                  }

                  void clear_pixel(RGBTRIPLE colour){
                  colour.rgbtBlue = 0;
                  colour.rgbtGreen = 0;
                  colour.rgbtRed = 0;
                  }

                  void avg(RGBTRIPLE colour[], RGBTRIPLE merge, int size) {
                  unsigned int blue = 0, green = 0, red = 0;
                  for(int i=0; i blue += colour[i].rgbtBlue;
                  green += colour[i].rgbtGreen;
                  red += colour[i].rgbtRed;
                  }
                  merge.rgbtBlue = blue / size;
                  merge.rgbtGreen= green / size;
                  merge.rgbtRed = red / size;
                  }

                  int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                  LPSTR lpCmdLine, int nCmdShow)
                  {

                  ZeroMemory (&bmp, sizeof bmp);
                  bmp.biClrImportant = 0;
                  bmp.biBitCount = 4;
                  bmp.biCompression = 0;
                  bmp.biPlanes = 1;
                  bmp.biSize = 40;
                  bmp.biSizeImage = 0;
                  bmp.biXPelsPerMeter = 0;
                  bmp.biYPelsPerMeter = 0;
                  bmp.biClrUsed = 16;
                  bmp.biHeight = 128;
                  bmp.biWidth = 128;

                  	long paddedsize = bmp.biHeight \* bmp.biWidth;
                  	bfh.bfType = 19778;
                  	bfh.bfReserved1 = 0;
                  	bfh.bfReserved2 = 0;
                  	bfh.bfOffBits = 1078;
                  	bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
                  

                  hfile = CreateFile("noise.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,NULL);

                  ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL);
                  ReadFile(hfile,&bmp,sizeof(bmp),&written,NULL);

                  int imagesize = bmp.biWidth*bmp.biHeight;
                  image = new RGBTRIPLE[imagesize];
                  ReadFile(hfile,image,sizeof(RGBTRIPLE),&written,NULL);

                  RGBTRIPLE blank[9]= { 0 };
                  RGBTRIPLE Merge = { 0 , 0 , 0 };
                  long yp=0, xp=0;

                  for(int y = 0; y < bmp.biHeight; y=y+3){
                  for(int x = 0; x < bmp.biWidth; x=x+3){
                  for(int i = 0; i < 9; i++){
                  int yp=0, xp=0;
                  get_pixel(x+xp,y+yp,blank[i]); // blank is an RGBTRIPLE array
                  if(xp<3)
                  xp++;
                  else{
                  xp = 0;
                  yp++;
                  } }
                  avg(blank, Merge, 9);
                  set_pixel(x,y,Merge);
                  for(int i = 0; i < 9; i++){
                  blank[i].rgbtBlue=0;
                  blank[i].rgbtGreen=0;
                  blank[i].rgbtRed=0;
                  }
                  clear_pixel(Merge);
                  yp=0, xp=0;
                  }}

                  EDIT: AHa! I've found something for(int i = 0; i < 9; i++){ int yp=0, xp=0; I declared yp and xp as int when I had already declared them as long. This w

                  T 1 Reply Last reply
                  0
                  • N Naturality

                    Okay, here's the full file(sans the reading/writing stuff)

                    void set_pixel(long x,long y, RGBTRIPLE colour){
                    image[(bmp.biHeight-1-y)*bmp.biWidth+x] = colour;
                    }

                    void get_pixel(int x, int y, RGBTRIPLE colour){
                    colour = image[(bmp.biHeight-1-y)*bmp.biWidth+x];
                    }

                    void clear_pixel(RGBTRIPLE colour){
                    colour.rgbtBlue = 0;
                    colour.rgbtGreen = 0;
                    colour.rgbtRed = 0;
                    }

                    void avg(RGBTRIPLE colour[], RGBTRIPLE merge, int size) {
                    unsigned int blue = 0, green = 0, red = 0;
                    for(int i=0; i blue += colour[i].rgbtBlue;
                    green += colour[i].rgbtGreen;
                    red += colour[i].rgbtRed;
                    }
                    merge.rgbtBlue = blue / size;
                    merge.rgbtGreen= green / size;
                    merge.rgbtRed = red / size;
                    }

                    int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine, int nCmdShow)
                    {

                    ZeroMemory (&bmp, sizeof bmp);
                    bmp.biClrImportant = 0;
                    bmp.biBitCount = 4;
                    bmp.biCompression = 0;
                    bmp.biPlanes = 1;
                    bmp.biSize = 40;
                    bmp.biSizeImage = 0;
                    bmp.biXPelsPerMeter = 0;
                    bmp.biYPelsPerMeter = 0;
                    bmp.biClrUsed = 16;
                    bmp.biHeight = 128;
                    bmp.biWidth = 128;

                    	long paddedsize = bmp.biHeight \* bmp.biWidth;
                    	bfh.bfType = 19778;
                    	bfh.bfReserved1 = 0;
                    	bfh.bfReserved2 = 0;
                    	bfh.bfOffBits = 1078;
                    	bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
                    

                    hfile = CreateFile("noise.bmp",GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING,NULL,NULL);

                    ReadFile(hfile,&bfh,sizeof(bfh),&written,NULL);
                    ReadFile(hfile,&bmp,sizeof(bmp),&written,NULL);

                    int imagesize = bmp.biWidth*bmp.biHeight;
                    image = new RGBTRIPLE[imagesize];
                    ReadFile(hfile,image,sizeof(RGBTRIPLE),&written,NULL);

                    RGBTRIPLE blank[9]= { 0 };
                    RGBTRIPLE Merge = { 0 , 0 , 0 };
                    long yp=0, xp=0;

                    for(int y = 0; y < bmp.biHeight; y=y+3){
                    for(int x = 0; x < bmp.biWidth; x=x+3){
                    for(int i = 0; i < 9; i++){
                    int yp=0, xp=0;
                    get_pixel(x+xp,y+yp,blank[i]); // blank is an RGBTRIPLE array
                    if(xp<3)
                    xp++;
                    else{
                    xp = 0;
                    yp++;
                    } }
                    avg(blank, Merge, 9);
                    set_pixel(x,y,Merge);
                    for(int i = 0; i < 9; i++){
                    blank[i].rgbtBlue=0;
                    blank[i].rgbtGreen=0;
                    blank[i].rgbtRed=0;
                    }
                    clear_pixel(Merge);
                    yp=0, xp=0;
                    }}

                    EDIT: AHa! I've found something for(int i = 0; i < 9; i++){ int yp=0, xp=0; I declared yp and xp as int when I had already declared them as long. This w

                    T Offline
                    T Offline
                    Tim Craig
                    wrote on last edited by
                    #9

                    Ok, a few more rookie gotchas. RGBTRIPLE is a struct. In get_pixel() and clear_pixel(), you want to operate on the pixel "colour" that you pass in. However, the way you've written it, you're working on a copy so you're changing nothing. You need to declare it as a pointer or a reference, RGBTRIPLE* pColour or RGBTRIPLE& colour. If you do it as a reference, you don't need to change the code inside the functions to pointer notation. The same thing applies to merge in avg(), you're working on a copy inside the function the passed parameter doesn't change. I also don't think you're applying the kernel to your image properly. I'm not up on gaussian off the top of my head but you need to apply it to every pixel and its immediate neighbors so bumping the index of the loops by 3 each pass doesn't do it. Usually, applying a kernel you need a source image and then build a spearate destination image, otherwise you'd be using pixels you've already changed as you progress through.

                    If you don't have the data, you're just another asshole with an opinion.

                    N 1 Reply Last reply
                    0
                    • T Tim Craig

                      Ok, a few more rookie gotchas. RGBTRIPLE is a struct. In get_pixel() and clear_pixel(), you want to operate on the pixel "colour" that you pass in. However, the way you've written it, you're working on a copy so you're changing nothing. You need to declare it as a pointer or a reference, RGBTRIPLE* pColour or RGBTRIPLE& colour. If you do it as a reference, you don't need to change the code inside the functions to pointer notation. The same thing applies to merge in avg(), you're working on a copy inside the function the passed parameter doesn't change. I also don't think you're applying the kernel to your image properly. I'm not up on gaussian off the top of my head but you need to apply it to every pixel and its immediate neighbors so bumping the index of the loops by 3 each pass doesn't do it. Usually, applying a kernel you need a source image and then build a spearate destination image, otherwise you'd be using pixels you've already changed as you progress through.

                      If you don't have the data, you're just another asshole with an opinion.

                      N Offline
                      N Offline
                      Naturality
                      wrote on last edited by
                      #10

                      "a few more rookie gotchas." Very rookie :laugh: I've changed the code as you suggested, with a source and destination file. But I get in the output file is a black image with some very dark green lines going vertically across. ::confused: Changed it a bit to use a 1,2,1, Matrix. This gives blue and green lines. Gah this is messed up. 2,4,2, 1,2,1 Here's the entire source... again.

                      // Bitmapblur.cpp : Defines the entry point for the application.
                      //

                      #include "stdafx.h"
                      #include
                      #include

                      HANDLE hfile;
                      HANDLE hfile2;
                      DWORD written;
                      BITMAPFILEHEADER bfh;
                      BITMAPINFOHEADER bmp;
                      RGBTRIPLE *image;

                      void set_pixel(long x,long y, RGBTRIPLE& colour){
                      image[bmp.biHeight+y*bmp.biWidth+x] = colour;
                      }

                      void get_pixel(int x, int y, RGBTRIPLE& colour){
                      colour = image[bmp.biHeight+y*bmp.biWidth+x];
                      }

                      void clear_pixel(RGBTRIPLE& colour){
                      colour.rgbtBlue = 0;
                      colour.rgbtGreen = 0;
                      colour.rgbtRed = 0;
                      }

                      void copy_pixel(RGBTRIPLE& colour, RGBTRIPLE& colour2){
                      colour.rgbtBlue = colour2.rgbtBlue;
                      colour.rgbtGreen = colour2.rgbtGreen;
                      colour.rgbtRed = colour2.rgbtRed;
                      }

                      void avg(RGBTRIPLE colour[], RGBTRIPLE& merge, int size, BYTE Matrix[]) {
                      unsigned int blue = 0, green = 0, red = 0;
                      for(int i=0; i blue += colour[i].rgbtBlue * Matrix[i] / 16;
                      green += colour[i].rgbtGreen * Matrix[i] / 16;
                      red += colour[i].rgbtRed * Matrix[i] / 16;
                      }
                      merge.rgbtBlue = blue / size;
                      merge.rgbtGreen= green / size;
                      merge.rgbtRed = red / size;
                      }

                      BYTE Matrix[9] = { 1, 2, 1,
                      2, 4, 2,
                      1, 2, 1 };

                      int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                      LPSTR lpCmdLine, int nCmdShow)
                      {

                      ZeroMemory (&bmp, sizeof bmp);
                      bmp.biClrImportant = 0;
                      bmp.biBitCount = 8;
                      bmp.biCompression = 0;
                      bmp.biPlanes = 1;
                      bmp.biSize = 40;
                      bmp.biSizeImage = 0;
                      bmp.biXPelsPerMeter = 0;
                      bmp.biYPelsPerMeter = 0;
                      bmp.biClrUsed = 0;
                      bmp.biHeight = 128;
                      bmp.biWidth = 128;

                      	long paddedsize = bmp.biHeight \* bmp.biWidth;
                      	bfh.bfType = 19778;
                      	bfh.bfReserved1 = 0;
                      	bfh.bfReserved2 = 0;
                      	bfh.bfOffBits = 1078;
                      	bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
                      

                      hfile = CreateFile("noisein.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
                      hfile2 = CreateFile("noiseout.bmp",GENERIC_WRIT

                      T 1 Reply Last reply
                      0
                      • N Naturality

                        "a few more rookie gotchas." Very rookie :laugh: I've changed the code as you suggested, with a source and destination file. But I get in the output file is a black image with some very dark green lines going vertically across. ::confused: Changed it a bit to use a 1,2,1, Matrix. This gives blue and green lines. Gah this is messed up. 2,4,2, 1,2,1 Here's the entire source... again.

                        // Bitmapblur.cpp : Defines the entry point for the application.
                        //

                        #include "stdafx.h"
                        #include
                        #include

                        HANDLE hfile;
                        HANDLE hfile2;
                        DWORD written;
                        BITMAPFILEHEADER bfh;
                        BITMAPINFOHEADER bmp;
                        RGBTRIPLE *image;

                        void set_pixel(long x,long y, RGBTRIPLE& colour){
                        image[bmp.biHeight+y*bmp.biWidth+x] = colour;
                        }

                        void get_pixel(int x, int y, RGBTRIPLE& colour){
                        colour = image[bmp.biHeight+y*bmp.biWidth+x];
                        }

                        void clear_pixel(RGBTRIPLE& colour){
                        colour.rgbtBlue = 0;
                        colour.rgbtGreen = 0;
                        colour.rgbtRed = 0;
                        }

                        void copy_pixel(RGBTRIPLE& colour, RGBTRIPLE& colour2){
                        colour.rgbtBlue = colour2.rgbtBlue;
                        colour.rgbtGreen = colour2.rgbtGreen;
                        colour.rgbtRed = colour2.rgbtRed;
                        }

                        void avg(RGBTRIPLE colour[], RGBTRIPLE& merge, int size, BYTE Matrix[]) {
                        unsigned int blue = 0, green = 0, red = 0;
                        for(int i=0; i blue += colour[i].rgbtBlue * Matrix[i] / 16;
                        green += colour[i].rgbtGreen * Matrix[i] / 16;
                        red += colour[i].rgbtRed * Matrix[i] / 16;
                        }
                        merge.rgbtBlue = blue / size;
                        merge.rgbtGreen= green / size;
                        merge.rgbtRed = red / size;
                        }

                        BYTE Matrix[9] = { 1, 2, 1,
                        2, 4, 2,
                        1, 2, 1 };

                        int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                        LPSTR lpCmdLine, int nCmdShow)
                        {

                        ZeroMemory (&bmp, sizeof bmp);
                        bmp.biClrImportant = 0;
                        bmp.biBitCount = 8;
                        bmp.biCompression = 0;
                        bmp.biPlanes = 1;
                        bmp.biSize = 40;
                        bmp.biSizeImage = 0;
                        bmp.biXPelsPerMeter = 0;
                        bmp.biYPelsPerMeter = 0;
                        bmp.biClrUsed = 0;
                        bmp.biHeight = 128;
                        bmp.biWidth = 128;

                        	long paddedsize = bmp.biHeight \* bmp.biWidth;
                        	bfh.bfType = 19778;
                        	bfh.bfReserved1 = 0;
                        	bfh.bfReserved2 = 0;
                        	bfh.bfOffBits = 1078;
                        	bfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + paddedsize;
                        

                        hfile = CreateFile("noisein.bmp",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,NULL,NULL);
                        hfile2 = CreateFile("noiseout.bmp",GENERIC_WRIT

                        T Offline
                        T Offline
                        Tim Craig
                        wrote on last edited by
                        #11

                        Ok, you have two files now but you only still have one bitmap in memory, especially the image variable. You're reading from it, operating on the pixels, and writing them back in place. You read the first file into memory and immediately read over the data in memory from the second. Not good. If you're going to use a global for the pixel matrix, get_pixel would have to work on the original image and set_pixel on the output image. A better way would be to write general functions that have a pointer to the pixel matrix as a parameter, then you'd be set. The other thing that has jarred my consciousness is the calcualtion of the index when you're accessing a pixel in image, ie "image[bmp.biHeight+y*bmp.biWidth+x]". Why the offset "bmp.biHeight"? Shouldn't the index to the pixel just be "y*bmp.biWidth+x"? Hard to tell some of this since for some reason your for loops don't seem to copy well. Are you using tabs in your code rather than spaces? Anyhow, it looks like you're closing in on doing the loop ranges on row and column properly from how I remember kernels. The starting index being one, however, you need to subtract 1 from the end test or you'll run off the edge. More properly, you have to allow a border of KernelSize/2 around the edge of your image since you can't really apply a kernel to those pixels. I'm not sure the stuff in the middle is correct but it's hard to make out. You're going to force me to actually look up Gaussian blur. :sigh:

                        If you don't have the data, you're just another asshole with an opinion.

                        N 2 Replies Last reply
                        0
                        • T Tim Craig

                          Ok, you have two files now but you only still have one bitmap in memory, especially the image variable. You're reading from it, operating on the pixels, and writing them back in place. You read the first file into memory and immediately read over the data in memory from the second. Not good. If you're going to use a global for the pixel matrix, get_pixel would have to work on the original image and set_pixel on the output image. A better way would be to write general functions that have a pointer to the pixel matrix as a parameter, then you'd be set. The other thing that has jarred my consciousness is the calcualtion of the index when you're accessing a pixel in image, ie "image[bmp.biHeight+y*bmp.biWidth+x]". Why the offset "bmp.biHeight"? Shouldn't the index to the pixel just be "y*bmp.biWidth+x"? Hard to tell some of this since for some reason your for loops don't seem to copy well. Are you using tabs in your code rather than spaces? Anyhow, it looks like you're closing in on doing the loop ranges on row and column properly from how I remember kernels. The starting index being one, however, you need to subtract 1 from the end test or you'll run off the edge. More properly, you have to allow a border of KernelSize/2 around the edge of your image since you can't really apply a kernel to those pixels. I'm not sure the stuff in the middle is correct but it's hard to make out. You're going to force me to actually look up Gaussian blur. :sigh:

                          If you don't have the data, you're just another asshole with an opinion.

                          N Offline
                          N Offline
                          Naturality
                          wrote on last edited by
                          #12

                          :laugh: That's the saddest face I've ever seen. I'll get right onto fixing those things. If it works, thanks for the advice.

                          "Sir, I protest. I am NOT a merry man!"

                          1 Reply Last reply
                          0
                          • T Tim Craig

                            Ok, you have two files now but you only still have one bitmap in memory, especially the image variable. You're reading from it, operating on the pixels, and writing them back in place. You read the first file into memory and immediately read over the data in memory from the second. Not good. If you're going to use a global for the pixel matrix, get_pixel would have to work on the original image and set_pixel on the output image. A better way would be to write general functions that have a pointer to the pixel matrix as a parameter, then you'd be set. The other thing that has jarred my consciousness is the calcualtion of the index when you're accessing a pixel in image, ie "image[bmp.biHeight+y*bmp.biWidth+x]". Why the offset "bmp.biHeight"? Shouldn't the index to the pixel just be "y*bmp.biWidth+x"? Hard to tell some of this since for some reason your for loops don't seem to copy well. Are you using tabs in your code rather than spaces? Anyhow, it looks like you're closing in on doing the loop ranges on row and column properly from how I remember kernels. The starting index being one, however, you need to subtract 1 from the end test or you'll run off the edge. More properly, you have to allow a border of KernelSize/2 around the edge of your image since you can't really apply a kernel to those pixels. I'm not sure the stuff in the middle is correct but it's hard to make out. You're going to force me to actually look up Gaussian blur. :sigh:

                            If you don't have the data, you're just another asshole with an opinion.

                            N Offline
                            N Offline
                            Naturality
                            wrote on last edited by
                            #13

                            GAHH!!! Another grey and black screen! Here's the current file.[^]

                            "Sir, I protest. I am NOT a merry man!"

                            T 2 Replies Last reply
                            0
                            • N Naturality

                              GAHH!!! Another grey and black screen! Here's the current file.[^]

                              "Sir, I protest. I am NOT a merry man!"

                              T Offline
                              T Offline
                              Tim Craig
                              wrote on last edited by
                              #14

                              Ok, a few things for you to think about while I'm trying to figure out your pixel indexing scheme. You read the second file, the output file, into memory. Why? You simply want to calculate the new image and write it? You never free the memory you allocated for the two image arrays. Won't kill you in this instance but bad practice. It doesn't look like you close the output file before you exit. I think Windows will do this for you but I never trust Windows to do anything I can do explicitly. It saves big teeth marks in your ass if it doesn't actually do what it's advertised to do. I'll get back to you on the rest of it.

                              If you don't have the data, you're just another asshole with an opinion.

                              1 Reply Last reply
                              0
                              • N Naturality

                                GAHH!!! Another grey and black screen! Here's the current file.[^]

                                "Sir, I protest. I am NOT a merry man!"

                                T Offline
                                T Offline
                                Tim Craig
                                wrote on last edited by
                                #15

                                Ok, courtesy of Wikipedia I've brushed up on Gaussian blurring. :cool: You're trying to replace each pixel, well at last those not on an edge with a weighted average of itself and the 8 pixels surrounding it. You have your weights in the array and are multiplying the pixel by the weight and diving by the sum of the weights (16). Two things. First and most glaring is why do you divide the blurred values by "size", 9 on your case? That's going to make things dark as you just cut each pixel value to 1/9 of its value, something less than 23 maximum out of the possible 255 if I did that right. Second, you'd be more accurate to do the division after you've fully accumulated the 9 weighted pixel values. The way you have it, you get a little truncation for each of the 9. If you wait until the end, you only get the truncation once. So get rid of the division by 16 in the loop and replace "size" by 16 at the end. Now to figure out how you're getting the 9 pixels to average. All I know for sure is that I'm 99.9% sure what you're doing isn't right. :suss:

                                If you don't have the data, you're just another asshole with an opinion.

                                N 1 Reply Last reply
                                0
                                • T Tim Craig

                                  Ok, courtesy of Wikipedia I've brushed up on Gaussian blurring. :cool: You're trying to replace each pixel, well at last those not on an edge with a weighted average of itself and the 8 pixels surrounding it. You have your weights in the array and are multiplying the pixel by the weight and diving by the sum of the weights (16). Two things. First and most glaring is why do you divide the blurred values by "size", 9 on your case? That's going to make things dark as you just cut each pixel value to 1/9 of its value, something less than 23 maximum out of the possible 255 if I did that right. Second, you'd be more accurate to do the division after you've fully accumulated the 9 weighted pixel values. The way you have it, you get a little truncation for each of the 9. If you wait until the end, you only get the truncation once. So get rid of the division by 16 in the loop and replace "size" by 16 at the end. Now to figure out how you're getting the 9 pixels to average. All I know for sure is that I'm 99.9% sure what you're doing isn't right. :suss:

                                  If you don't have the data, you're just another asshole with an opinion.

                                  N Offline
                                  N Offline
                                  Naturality
                                  wrote on last edited by
                                  #16

                                  Well, this those changes, it now comes out red and black instead of grey and black. I'm Sure I'm doing it wrong too. :sigh:

                                  "Sir, I protest. I am NOT a merry man!"

                                  C 1 Reply Last reply
                                  0
                                  • N Naturality

                                    Well, this those changes, it now comes out red and black instead of grey and black. I'm Sure I'm doing it wrong too. :sigh:

                                    "Sir, I protest. I am NOT a merry man!"

                                    C Offline
                                    C Offline
                                    Christian Graus
                                    wrote on last edited by
                                    #17

                                    If the colors are changing, then what you're doing wrong is your pixel lookup, the colors are bleeding between red, green and blue. Did you read my article which has a guassian blur filter in it ?

                                    Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )

                                    N 1 Reply Last reply
                                    0
                                    • C Christian Graus

                                      If the colors are changing, then what you're doing wrong is your pixel lookup, the colors are bleeding between red, green and blue. Did you read my article which has a guassian blur filter in it ?

                                      Christian Graus Please read this if you don't understand the answer I've given you "also I don't think "TranslateOneToTwoBillion OneHundredAndFortySevenMillion FourHundredAndEightyThreeThousand SixHundredAndFortySeven()" is a very good choice for a function name" - SpacixOne ( offering help to someone who really needed it ) ( spaces added for the benefit of people running at < 1280x1024 )

                                      N Offline
                                      N Offline
                                      Naturality
                                      wrote on last edited by
                                      #18

                                      Yes, I did. However, I don't see how my pixel lookup is wrong. :S

                                      "Sir, I protest. I am NOT a merry man!"

                                      T 1 Reply Last reply
                                      0
                                      • N Naturality

                                        Yes, I did. However, I don't see how my pixel lookup is wrong. :S

                                        "Sir, I protest. I am NOT a merry man!"

                                        T Offline
                                        T Offline
                                        Tim Craig
                                        wrote on last edited by
                                        #19

                                        Ok, for starters I believe you're scanning the input image correctly now, x and y cover the correct pixels. However, you want to grab 3 pixels from the previous row right above the target pixel, three from the current row including the two on either side of the target, and the from the next row. So xp and yp have to take the values, [-1, 0, 1]. You start with 0 and your test of xp < 4 actually makes xp go from 0, 1, 2, 3. So you're getting the wrong pixel correlated. Also, after you call avg(), you should only be setting 1 pixel in the output image, the one at x, y. So the second set of for loops need to vanish.

                                        If you don't have the data, you're just another asshole with an opinion.

                                        N 1 Reply Last reply
                                        0
                                        • T Tim Craig

                                          Ok, for starters I believe you're scanning the input image correctly now, x and y cover the correct pixels. However, you want to grab 3 pixels from the previous row right above the target pixel, three from the current row including the two on either side of the target, and the from the next row. So xp and yp have to take the values, [-1, 0, 1]. You start with 0 and your test of xp < 4 actually makes xp go from 0, 1, 2, 3. So you're getting the wrong pixel correlated. Also, after you call avg(), you should only be setting 1 pixel in the output image, the one at x, y. So the second set of for loops need to vanish.

                                          If you don't have the data, you're just another asshole with an opinion.

                                          N Offline
                                          N Offline
                                          Naturality
                                          wrote on last edited by
                                          #20

                                          Thanks for the advice :D. But now, the output is just red and black lines :doh: Here's the updated code:

                                          unsigned int yp=0, xp=0;

                                          for(int y = 1; y < bmp.biHeight-1; y++){
                                          for(int x = 1; x < bmp.biWidth-1; x++){
                                          for(int i = 0; i < 9; i++){
                                          {
                                          get_pixel(x+xp,y+yp,blank[i],image);
                                          if(xp<2)
                                          xp++;
                                          else{
                                          xp = -1;
                                          yp++;}
                                          }
                                          }
                                          avg(blank, Merge, 9, Matrix);
                                          set_pixel(x,y,Merge,image2);
                                          clear_pixel(Merge);
                                          yp=-1, xp=-1;

                                          }}
                                          

                                          "Sir, I protest. I am NOT a merry man!"

                                          C T 3 Replies Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups