问题
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;
}
回答1:
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.
回答2:
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:
- It shifts all pixel values by -0.5 (so that a medium-gray becomes 0)
- It applies a factor to all pixel values
- 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);
来源:https://stackoverflow.com/questions/23865511/contrast-with-color-matrix