加速位图灰度转换,OpenMP 是 C# 中的一个选项吗?
Posted
技术标签:
【中文标题】加速位图灰度转换,OpenMP 是 C# 中的一个选项吗?【英文标题】:Accelerating bitmap grayscale conversion, is OpenMP an option in C#? 【发布时间】:2011-01-03 13:50:19 【问题描述】:请帮助我使用 openmp 使这段代码并行 此代码在按钮单击时运行,文本框为 128
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace IMG
public partial class Form1 : Form
public Form1()
InitializeComponent();
string path = "";
public void openimage()
if (openFileDialog1.ShowDialog() == DialogResult.OK)
path = openFileDialog1.FileName;
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
Bitmap curBitmap = new Bitmap(path);
g.DrawImage(curBitmap, 200, 220, 200, 200);
Bitmap bm;
Bitmap gs;
private void button1_Click(object sender, EventArgs e)
if (path == "")
openimage();
//mack image gray scale
Graphics g = this.CreateGraphics();
g.Clear(this.BackColor);
// Create a Bitmap object
bm = new Bitmap(path);
// Draw image with no effects
g.DrawImage(bm, 200, 220, 200, 200);
gs = new Bitmap(bm.Width, bm.Height);
for (int i = 0; i < bm.Width; i++)
for (int j = 0; j < bm.Height; j++)
Color c = bm.GetPixel(i, j);
int y = (int)(0.3 * c.R + 0.59 * c.G + 0.11 * c.B);
gs.SetPixel(i, j, Color.FromArgb(y, y, y));
// Draw image with no effects
g.DrawImage(gs, 405, 220, 200, 200);
for (int i = 0; i < gs.Width; i++)
for (int j = 0; j < gs.Height; j++)
Color c = gs.GetPixel(i, j);
int y1 = 0;
if (c.R >= Convert.ToInt16(textBox19.Text))
y1 = 255;
bm.SetPixel(i, j, Color.FromArgb(y1, y1, y1));
g.DrawImage(bm, new Rectangle(610, 220, 200, 200), 0, 0, bm.Width, bm.Height, GraphicsUnit.Pixel);
// Dispose of objects
gs.Dispose();
g.Dispose();
如果我相信这个网站和这里的所有程序员,请尽快帮助我...
【问题讨论】:
OpenMP 规范仅涵盖 C、C++ 和 Fortran。没有 C#,而且 AFAIK 微软也没有在他们的 C# 编译器中实现类似的东西。 【参考方案1】:为什么要让这段代码并行?获得处理效率(时间) ?如果是这样,我认为在并行处理此代码之前,您可以尝试一种不同的方法来访问图像中的像素信息。
您在这段代码中执行的方式非常慢。您可以尝试使用不安全的代码来处理您的图像,以访问 Bitmap 类的像素。
看看at this thread,看看我在说什么
【讨论】:
【参考方案2】:如果 OpenMP 出现在您的视野中,您会遇到几个减速带。 OpenMP 是用于非托管 C/C++ 的多线程库,它需要编译器支持才能有效。在 C# 中不是一个选项。
让我们退后一步。你现在得到的已经是你所能得到的最糟糕的了。 Get/SetPixel() 非常慢。一个主要步骤是使用 Bitmap.LockBits(),它为您提供位图位的 IntPtr。您可以使用不安全的字节指针来参与这些位。这将至少快一个数量级。
让我们再退一步,您显然是在编写将彩色图像转换为灰度图像的代码。 GDI+ 通过 ColorMatrix 类原生支持颜色变换。该代码可能如下所示:
public static Image ConvertToGrayScale(Image srce)
Bitmap bmp = new Bitmap(srce.Width, srce.Height);
using (Graphics gr = Graphics.FromImage(bmp))
var matrix = new float[][]
new float[] 0.299f, 0.299f, 0.299f, 0, 0 ,
new float[] 0.587f, 0.587f, 0.587f, 0, 0 ,
new float[] 0.114f, 0.114f, 0.114f, 0, 0 ,
new float[] 0, 0, 0, 1, 0 ,
new float[] 0, 0, 0, 0, 1
;
var ia = new System.Drawing.Imaging.ImageAttributes();
ia.SetColorMatrix(new System.Drawing.Imaging.ColorMatrix(matrix));
var rc = new Rectangle(0, 0, srce.Width, srce.Height);
gr.DrawImage(srce, rc, 0, 0, srce.Width, srce.Height, GraphicsUnit.Pixel, ia);
return bmp;
感谢Bob Powell: How to convert a colour image to grayscale 以上代码。
【讨论】:
以上是关于加速位图灰度转换,OpenMP 是 C# 中的一个选项吗?的主要内容,如果未能解决你的问题,请参考以下文章
用c#编写一个程序读取一张bmp图片的数据并转化为灰度图保存到文件中