Ускорение растрового переоборудования серого серого, является ли OpenMP опция в C#?
-
19-09-2019 - |
Вопрос
Пожалуйста, помогите мне сделать этот код параллелью, используя 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 будет на вашем радаре. 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;
}
}
Кредит Боб Пауэлл для приведенного выше кода.
Другие советы
Почему вы хотите сделать этот код параллельным? Чтобы получить эффективность обработки (время)? Если это так, я думаю, что прежде чем повернуть этот код параллельно, вы можете попробовать другой подход в том, как вы получаете доступ к информации о пикселе на своем изображении.
То, как вы делаете в этом коде, очень медленно. Вы можете попытаться обработать свое изображение с помощью небезопасного кода для доступа к пикселям класса растрового изображения.
Взглянем в этой теме Чтобы увидеть, о чем я говорю