contrast with color matrix
Asked Answered
M

2

1

Hi I want to implement contrast filter in my application like this link or this contrast but with color matrix and track bar for value
I already found color matrix for it

float c = mytrackbar.value * 0.01f //maxTrackbarValue = 100, minTrackbarValue = -100 
float t = 0.01f;
cmPicture = new ColorMatrix(new float[][] {
    new float[] {c,0,0,0,0},
    new float[] {0,c,0,0,0},
    new float[] {0,0,c,0,0},
    new float[] {0,0,0,1,0},
    new float[] {t,t,t,0,1}
});

but the result is very different. I try to change 0.01f in ~c~ and 0.01f in ~t~ value but it only gives result like brightness (ex : c = mytrackbar.value * 0.04f )

I wonder what ~c~ & ~t~ value and how many max and min range i should used for created contrast


Update @Nico

    private void myTrackBar_ValueChanged(object sender, EventArgs e) {
        imageHandle = imageHandleTemp.Bitmap;
        myNumericUpDown.Text = myTrackBar.Value.ToString();
        float value = myTrackBar.Value * 0.01f;

        Bitmap bmpInverted = new Bitmap(imageHandle.Width, imageHandle.Height);
        ImageAttributes ia = new ImageAttributes();
        ColorMatrix cmPicture = new ColorMatrix();

        float c = value;
        float t = 0.01f;
        cmPicture = new ColorMatrix(new float[][] {
            new float[] {c,0,0,0,0},
            new float[] {0,c,0,0,0},
            new float[] {0,0,c,0,0},
            new float[] {0,0,0,1,0},
            new float[] {t,t,t,0,1}
        });

        ia.SetColorMatrix(cmPicture);
        Graphics g = Graphics.FromImage(bmpInverted);
        g.DrawImage(imageHandle, new Rectangle(0, 0, imageHandle.Width, imageHandle.Height), 0, 0, imageHandle.Width, imageHandle.Height, GraphicsUnit.Pixel, ia);
        g.Dispose();

        Image<Bgr, Byte> myImage = new Image<Bgr, byte>(bmpInverted);
        imageBoxCamera.Image = myImage;
    }
Milligram answered 26/5, 2014 at 8:5 Comment(3)
Please add the relevant parts of your code. How do you apply this matrix?Ti
Check out this link. It says that t = (1.0 - c) / 2.0 and c = contrast. All values go from 0 to 1.Talithatalk
@Talithatalk i'm sory but tthe result still same i used this code t=(float)(1.0 - c) / 2.0, t = (1.0 - c) / 2.0 is double so i need to cast to float..please check my updated post too maybe u can help fix itMilligram
T
3

The t value must be derived from the new contrast value c. so change its assignment like this:

float t = (1.0f - c) / 2.0f;

According to this nice link to the ColorMatrix Guide the rest of the matrix code seems to be OK.

Note: I was wrong about the range of c!! The value of c is not an absolute value but it is the factor that should be applied! So to double the contrast it should be 2f.

Note 2: Your code is not quite clear about source and target; and since you are changing contrast on the fly with the trackbar it should be clear that until the change is applied,

  • The intermediate results must always be calculated from the same original bitmap.

  • Also, that the trackbar should be so intialized that it starts with a value of 1.

  • And finally, in order to reduce contrast values should translate to 0 < c < 1.

Nico's suggestion c = 1+ value; would work nicely with your original range -100 to +100 with an intial value of 0 and your factor 0.01f.

Talithatalk answered 26/5, 2014 at 9:14 Comment(2)
hm...i think the problem now is from limit max & min trackbar value...i used 100 as max & -100 as min....when trackbar max value the image become normal & when in minimum it's almost same as negativeMilligram
ha, I didn't see that as it was just out of sight. Also: I was wrong in my comment about the range of c! It isn't an absolute value but a factor!! So to double the contrast it should be 2f.Talithatalk
T
3

Here are some further explanations about the maths behind the process. If you are going to accept an answer, accept TaW's answer, he was quicker than me.

Adjusting the contrast basically does the following:

  1. It shifts all pixel values by -0.5 (so that a medium-gray becomes 0)
  2. It applies a factor to all pixel values
  3. It reverts the shift

So in a formula:

newValue = factor * (oldValue - 0.5) + 0.5
         = factor * oldValue - factor * 0.5 + 0.5
         = factor * oldValue + 0.5 * (1 - factor)

For a single-channel image we can transform this into a matrix multiplication:

(newValue, 1) = (oldValue, 1) * /        factor      , 0\     <-- this is c, 0
                                \ 0.5 * (1 - factor) , 1/     <-- this is t, 1

For multi-channel images, the 2x2 matrix becomes a 5x5 (four channels + w-channel for translations) matrix with c and t at the positions you already specified.

Keep in mind that a factor of 1 does not change anything. A factor of 0 makes the whole image medium-gray. So you may want to adjust your calculation of c:

c = 1 + value;
t = 0.5f * (1.0f - c);
Ti answered 26/5, 2014 at 9:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.