2

I have the following code to show my senor data in 2D interpolated color map. However, I would like to transform it into a 3D mesh surface. I can only find some complicated methods to do that. But what I am thinking is an easier way which can pull the 2D color map to a higher level according to its different colors on each data array to make the 2D bitmap like 3D

2D and 3D bitmap

Bitmap bmp3 = new Bitmap(PicBoxChi.Width, PicBoxChi.Height);
using (Graphics g = Graphics.FromImage(bmp3))
{
    // this loop create a 6X4 map to show my sensor data
    for (int a = 0; a < 6; a++)
    {
        for (int b = 0; b < 4; b++)
        {
            pts[a, b] = new PointC(new PointF(x0 + b*width, y0 + a*height), data[a*4+b+48] ); 
        }
    }


    int colorLength = cmap.GetLength(0);
    // Bilinear interpolation:

    // this loop transfer my 6x4 sensor data map to a color map
    for (int i = 0; i < 5; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            PointF[] pta = new PointF[4]{pts[i,j].pointf, pts[i+1,j].pointf,
            pts[i+1,j+1].pointf, pts[i,j+1].pointf};
            float[] cdata = new float[4]{pts[i,j].C,pts[i+1,j].C,
            pts[i+1,j+1].C,pts[i,j+1].C};
            Interp(g, pta, cdata, 50);
        }
    }

}

I can now create the 2D color bitmap by above code. But I have no idea to make the 3D one as shown in figure.

Wai Ka
  • 43
  • 7
  • 1
    The act of compiling a 3D mesh made out of triangles from a rectangular image knowing the height isn't very hard by itself. From what i can understand, finding the height of every pixel is the problem, right? – user2464424 Jan 04 '16 at 10:12
  • Please clarify whether you are having trouble with the color->height function and/or if you need help with the 3D mesh generation. – Mr_Pouet Jan 04 '16 at 16:59
  • @user2464424 yes, I couldn't find the height of every pixel. – Wai Ka Jan 05 '16 at 03:25
  • 1
    @Mr_Pouet I need help with the 3D mesh generation. The picture as shown is the 3D mesh surface I would like to build. I could only find a matrix transformation method to generate the 3D surface, but the color->height function is my thought to generate this 3D mesh. Thank you so much if you can give help on generating 3D mesh – Wai Ka Jan 05 '16 at 03:27

1 Answers1

0

If the pixel colors are in RGB format, from the provided picture I can infer that what you are interested in is the pure Hue of the color.

To get a standard [0, 360] ranged hue value from RGB you can do like this:

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
float hue = color.GetHue();

or a more customizable approach (here in Java, reporting it here too):

public int getHue(int red, int green, int blue) {

    float min = Math.min(Math.min(red, green), blue);
    float max = Math.max(Math.max(red, green), blue);

    float hue = 0f;
    if (max == red) {
        hue = (green - blue) / (max - min);

    } else if (max == green) {
        hue = 2f + (blue - red) / (max - min);

    } else {
        hue = 4f + (red - green) / (max - min);
    }

    hue = hue * 60;
    if (hue < 0) hue = hue + 360;

    return Math.round(hue);
}

You can then simply use the resulting value as the height of the corresponding vertex, optionally fine-tuning it by dividing/multiplying it by some constant.

Generating the 3D mesh is relatively simple and i think you already have the code in place, here's a pseudocode anyway:

float getHeight(img img, int x, int y) {
    float scalefactor = 1.0/360; //any value you like
    return getHue(getRgbColorFromImage(img, x, y)) * scalefactor;
}


int x=0, y=0;
for (y=0; y<imageHeight-1; y++) {
    for (x=0; x<imageWidth-1; x++) {
        new quad = [x, y, getHeight(img, x, y),
                    x+1, y, getHeight(img, x+1, y),
                    x, y+1, getHeight(img, x, y+1),
                    x+1, y+1, getHeight(img, x+1, y+1)];
    }
}

if you want triangles:

new triangle = [x, y, getHeight(img, x, y),
                x+1, y, getHeight(img, x+1, y),
                x, y+1, getHeight(img, x, y+1)];
new triangle = [x+1, y, getHeight(img, x+1, y),
                x, y+1, getHeight(img, x, y+1),
                x+1, y+1, getHeight(img, x+1, y+1)];
Community
  • 1
  • 1
user2464424
  • 1,536
  • 1
  • 14
  • 28
  • hello there, I tried to use your code. but so many errors exist and I couldn't really fix it. Can you give some helps? Error CS0103 The name 'img' does not exist in the current context; Error CS0103 The name 'getRgbColorFromImage' does not exist in the current context – Wai Ka Feb 18 '16 at 05:26
  • @WaiKa mh, the last code there is a pseudocode, you are supposed to traslate it in your language of preference. of course it gives errors! but you said in a comment that only getting the height was the issue so i posted first some approaches to compute a height function and the last snippet is just for 'wrapping the package'. – user2464424 Feb 18 '16 at 11:46
  • really thz for your reply. Not only getting height was the issue. I have no idea to generate the 3D mesh as shown on attached image. And my idea is adding a height to its 2D color bitmap – Wai Ka Feb 24 '16 at 09:04
  • Since I don't know how to apply your getHue function to generate corresponding 3D mesh surface – Wai Ka Feb 24 '16 at 09:24