PictureWork.cs
Home
/
NeuralNetwork /
NeuralNetwork.PictureWork /
PictureWork.cs
using System;
using System.Collections.Generic;
using System.Drawing;
namespace NeuralNetwork.PictureWork
{
public static class PictureWork
{
/// <summary>
/// Заменяет прозрачные области белым цветом.
/// </summary>
/// <param name="src">Исходное изображение</param>
/// <returns></returns>
public static Bitmap RemoveTransparency(Bitmap src)
{
Bitmap target = new Bitmap(src.Size.Width, src.Size.Height);
Graphics g = Graphics.FromImage(target);
g.Clear(Color.White);
g.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceOver;
g.DrawImage(src, 0, 0);
return target;
}
/// <summary>
/// Выполняет поиск прямоугольных областей на рисунке, содержащих объекты.
/// </summary>
/// <param name="m">Матрица яркости пикселей значениями от 0 до 1.</param>
/// <returns>Возвращает массив прямоугольных областей, где были найдены объекты.</returns>
public static Rectangle[] FindObjects(float[][] m)
{
int y1 = -1, y2 = -1;
for (int i = 0; i < m.Length && y1 == -1; i++)
for (int j = 0; j < m[i].Length; j++)
if ((int)Math.Round(m[i][j]) == 1)
{
y1 = i;
break;
}
for (int i = m.Length - 1; i > y1 && y2 == -1; i--)
for (int j = 0; j < m[i].Length; j++)
if ((int)Math.Round(m[i][j]) == 1)
{
y2 = i;
break;
}
int xEnd = 0;
List<Rectangle> digits = new List<Rectangle>();
Rectangle current;
while (true)
{
current = FindObject(m, y1, y2, xEnd, ref xEnd);
if (current != Rectangle.Empty)
digits.Add(current);
else
break;
}
return digits.ToArray();
}
/// <summary>
/// Выполняет поиск объекта среди всей матрицы яркости в заданных границах
/// </summary>
/// <param name="m">Матрица яркости пикселей значениями от 0 до 1.</param>
/// <param name="y1">Верхняя граница поиска по высоте.</param>
/// <param name="y2">Нижняя граница поиска по высоте.</param>
/// <param name="xStart">Крайняя левая граница поиска по ширине.</param>
/// <param name="xEnd">Крайняя правая граница поиска по ширине.</param>
/// <returns>Возвращает прямоугольную область - границы найденного изображения.</returns>
public static Rectangle FindObject(float[][] m, int y1, int y2, int xStart, ref int xEnd)
{
int x1 = -1, x2 = -1;
for (int j = xStart; j < m[0].Length && x1 == -1; j++)
for (int i = y1; i < y2; i++)
if ((int)Math.Round(m[i][j]) == 1)
{
x1 = j;
break;
}
if (x1 != -1)
{
for (int j = x1 + 1, k; j < m[0].Length; j++)
{
k = 0;
for (int i = y1; i < y2; i++)
k += (int)Math.Round(m[i][j]);
if (k == 0)
{
x2 = j - 1;
break;
}
}
if (x2 == -1)
x2 = m.Length - 1;
xEnd = x2 + 1;
return new Rectangle(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
}
return Rectangle.Empty;
}
/// <summary>
/// Выполняет конвертацию изображения в матрицу яркости.
/// </summary>
/// <param name="bmp">Исходное изображение.</param>
/// <returns>Возвращает матрицу яркости пикселя значениями от 0 до 1.</returns>
public unsafe static float[][] BitmapToFloatMatrixRgbQ(Bitmap bmp)
{
int width = bmp.Width,
height = bmp.Height;
System.Drawing.Imaging.BitmapData bd = bmp.LockBits(
new Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb);
float[][] matrix = new float[height][];
try
{
unsafe
{
for (int h = 0; h < height; ++h)
{
matrix[h] = new float[width];
byte* row = (byte*)bd.Scan0 + (h * bd.Stride);
int columnOffset = 0;
for (int w = 0; w < width; ++w)
{
byte B = row[columnOffset];
byte G = row[columnOffset + 1];
byte R = row[columnOffset + 2];
columnOffset += 4;
matrix[h][w] = (255f - (float)Math.Round((R + G + B) / 3f)) / 256f;
}
}
}
}
finally
{
bmp.UnlockBits(bd);
}
return matrix;
}
/// <summary>
/// Выполняет конвертацию изображения в матрицу яркости.
/// </summary>
/// <param name="bmp">Исходное изображение.</param>
/// <returns>Возвращает матрицу яркости пикселя значениями от 0 до 1.</returns>
public unsafe static float[] BitmapToFloatArrayRgbQ(Bitmap bmp)
{
int width = bmp.Width,
height = bmp.Height;
System.Drawing.Imaging.BitmapData bd = bmp.LockBits(
new Rectangle(0, 0, width, height),
System.Drawing.Imaging.ImageLockMode.ReadOnly,
System.Drawing.Imaging.PixelFormat.Format32bppRgb);
float[] _array = new float[height * width];
try
{
unsafe
{
for (int h = 0; h < height; ++h)
{
byte* row = (byte*)bd.Scan0 + (h * bd.Stride);
int columnOffset = 0;
for (int w = 0; w < width; ++w)
{
byte B = row[columnOffset];
byte G = row[columnOffset + 1];
byte R = row[columnOffset + 2];
columnOffset += 4;
_array[h * height + w] = (255f - (float)Math.Round((R + G + B) / 3f)) / 256f;
}
}
}
}
finally
{
bmp.UnlockBits(bd);
}
return _array;
}
}
}