替换图像的颜色
Replacing colour of an Image
我正在尝试用白色替换图片的黑色,反之亦然。这实际上是为了让我的 OCR 代码可以在白色背景上更好地阅读它。目前正在从剪贴板获取图像
Image img = Clipboard.GetImage();
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = img;
我看到其他一些问题,他们正在处理实际的位图,但我如何直接从剪贴板处理它?
您可以使用 System.Drawimg.Imaging
命名空间中的 ColorMap and ImageAttributes 类 直接替换图像中的像素:
Image img = Clipboard.GetImage();
if (img != null) {
ColorMap[] cm = new ColorMap[1];
cm[0] = new ColorMap();
cm[0].OldColor = Color.Black;
cm[0].NewColor = Color.White;
ImageAttributes ia = new ImageAttributes();
ia.SetRemapTable(cm);
using (Graphics g = Graphics.FromImage(img)) {
g.DrawImage(img, new Rectangle(Point.Empty, img.Size), 0, 0, img.Width, img.Height,
GraphicsUnit.Pixel, ia);
}
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = img;
}
另一个解决方案使用 ColorMatrix class.
您可以使用 Graphics.DrawImage overload that accepts an ImageAttributes 参数。
ImageAttributes.SetColorMatrix()
设置颜色调整矩阵,可选择针对特定类别(位图、钢笔、画笔等),并且可以指示跳过灰色颜色,仅修改灰色颜色或所有颜色。
ImageAttributes.SetThreshold()
方法允许调节颜色截止点(阈值)以微调亮度。
它接受从 0
到 1
.
的值
当设置为 0
时,图像全白,当设置为 1
时图像全黑(参见文档)。
同时考虑到“反转”取决于原始位图颜色模式,因此尝试不同的方法。有时,反转亮度可以为您带来更好的效果,有时则不然。
您的 OCR 必须经过“训练”,以验证哪些值更适合它。
看看这些文章:
Recoloring (MSDN)
ASCII Art Generator (CodeProject)
亮度矩阵:
R=Red G=Green B=Blue A=Alpha Channel W=White (Brightness)
修改亮度组件以获得“反转”
R G B A W
R [1 0 0 0 0]
G [0 1 0 0 0]
B [0 0 1 0 0]
A [0 0 0 1 0]
W [b b b 0 1] <= Brightness
using System.Drawing;
using System.Drawing.Imaging;
// ...
Image colorImage = Clipboard.GetImage();
// Default values, no inversion, no threshold adjustment
var bmpBlackWhite = BitmapToBlackAndWhite(colorImage);
// Inverted, use threshold adjustment set to .75f
var bmpBlackWhite = BitmapToBlackAndWhite(colorImage, true, true, .75f);
// ...
private Bitmap BitmapToBlackAndWhite(Image image, bool invert = false, bool useThreshold = false, float threshold = .5f)
{
var mxBlackWhiteInverted = new float[][]
{
new float[] { -1, -1, -1, 0, 0},
new float[] { -1, -1, -1, 0, 0},
new float[] { -1, -1, -1, 0, 0},
new float[] { 0, 0, 0, 1, 0},
new float[] { 1, 1, 1, 0, 1}
};
var mxBlackWhite = new float[][]
{
new float[] { 1, 1, 1, 0, 0},
new float[] { 1, 1, 1, 0, 0},
new float[] { 1, 1, 1, 0, 0},
new float[] { 0, 0, 0, 1, 0},
new float[] {-1, -1, -1, 0, 1}
};
var bitmap = new Bitmap(image.Width, image.Height);
using (var g = Graphics.FromImage(bitmap))
using (var attributes = new ImageAttributes()) {
attributes.SetColorMatrix(new ColorMatrix(invert ? mxBlackWhiteInverted : mxBlackWhite));
// Adjust the threshold as needed
if (useThreshold) attributes.SetThreshold(threshold);
var rect = new Rectangle(Point.Empty, image.Size);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
return bitmap;
}
}
如果你的图片是黑白的,在OpenCV中很容易:
// bmp is your bitmap
var inverted = (255 - bitmap.ToMat()).ToMat().
.ToBitamp() // or
.ToWriteableBitmap() // or
.ToBitmapSource()
如果这是您对整个应用程序的唯一操作,OpenCV 可能有点矫枉过正
我正在尝试用白色替换图片的黑色,反之亦然。这实际上是为了让我的 OCR 代码可以在白色背景上更好地阅读它。目前正在从剪贴板获取图像
Image img = Clipboard.GetImage();
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = img;
我看到其他一些问题,他们正在处理实际的位图,但我如何直接从剪贴板处理它?
您可以使用 System.Drawimg.Imaging
命名空间中的 ColorMap and ImageAttributes 类 直接替换图像中的像素:
Image img = Clipboard.GetImage();
if (img != null) {
ColorMap[] cm = new ColorMap[1];
cm[0] = new ColorMap();
cm[0].OldColor = Color.Black;
cm[0].NewColor = Color.White;
ImageAttributes ia = new ImageAttributes();
ia.SetRemapTable(cm);
using (Graphics g = Graphics.FromImage(img)) {
g.DrawImage(img, new Rectangle(Point.Empty, img.Size), 0, 0, img.Width, img.Height,
GraphicsUnit.Pixel, ia);
}
pictureBox1.SizeMode = PictureBoxSizeMode.StretchImage;
pictureBox1.Image = img;
}
另一个解决方案使用 ColorMatrix class.
您可以使用 Graphics.DrawImage overload that accepts an ImageAttributes 参数。
ImageAttributes.SetColorMatrix()
设置颜色调整矩阵,可选择针对特定类别(位图、钢笔、画笔等),并且可以指示跳过灰色颜色,仅修改灰色颜色或所有颜色。
ImageAttributes.SetThreshold()
方法允许调节颜色截止点(阈值)以微调亮度。
它接受从 0
到 1
.
的值
当设置为 0
时,图像全白,当设置为 1
时图像全黑(参见文档)。
同时考虑到“反转”取决于原始位图颜色模式,因此尝试不同的方法。有时,反转亮度可以为您带来更好的效果,有时则不然。
您的 OCR 必须经过“训练”,以验证哪些值更适合它。
看看这些文章:
Recoloring (MSDN)
ASCII Art Generator (CodeProject)
亮度矩阵:
R=Red G=Green B=Blue A=Alpha Channel W=White (Brightness)
修改亮度组件以获得“反转”
R G B A W
R [1 0 0 0 0]
G [0 1 0 0 0]
B [0 0 1 0 0]
A [0 0 0 1 0]
W [b b b 0 1] <= Brightness
using System.Drawing;
using System.Drawing.Imaging;
// ...
Image colorImage = Clipboard.GetImage();
// Default values, no inversion, no threshold adjustment
var bmpBlackWhite = BitmapToBlackAndWhite(colorImage);
// Inverted, use threshold adjustment set to .75f
var bmpBlackWhite = BitmapToBlackAndWhite(colorImage, true, true, .75f);
// ...
private Bitmap BitmapToBlackAndWhite(Image image, bool invert = false, bool useThreshold = false, float threshold = .5f)
{
var mxBlackWhiteInverted = new float[][]
{
new float[] { -1, -1, -1, 0, 0},
new float[] { -1, -1, -1, 0, 0},
new float[] { -1, -1, -1, 0, 0},
new float[] { 0, 0, 0, 1, 0},
new float[] { 1, 1, 1, 0, 1}
};
var mxBlackWhite = new float[][]
{
new float[] { 1, 1, 1, 0, 0},
new float[] { 1, 1, 1, 0, 0},
new float[] { 1, 1, 1, 0, 0},
new float[] { 0, 0, 0, 1, 0},
new float[] {-1, -1, -1, 0, 1}
};
var bitmap = new Bitmap(image.Width, image.Height);
using (var g = Graphics.FromImage(bitmap))
using (var attributes = new ImageAttributes()) {
attributes.SetColorMatrix(new ColorMatrix(invert ? mxBlackWhiteInverted : mxBlackWhite));
// Adjust the threshold as needed
if (useThreshold) attributes.SetThreshold(threshold);
var rect = new Rectangle(Point.Empty, image.Size);
g.DrawImage(image, rect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, attributes);
return bitmap;
}
}
如果你的图片是黑白的,在OpenCV中很容易:
// bmp is your bitmap
var inverted = (255 - bitmap.ToMat()).ToMat().
.ToBitamp() // or
.ToWriteableBitmap() // or
.ToBitmapSource()
如果这是您对整个应用程序的唯一操作,OpenCV 可能有点矫枉过正