/// <summary> /// Строит луч от пикселя вверх /// </summary> /// <param name="image">Изображение, представляющее границы</param> /// <param name="fillingImage">Изображение для карты SWT</param> /// <param name="comparator">Функция сравнение интенсивностей пикселей</param> /// <param name="row">Номер строки пикселя, от которого строится луч</param> /// <param name="column">Номер столбца пикселя, от которого строится луч</param> private void TrackRayUp(GreyImage image, GreyImage fillingImage, List<Ray> rays, CompareIntensity comparator, int row, int column) { try { int imageHeight = image.Height; int rowFrom = row; row -= 1; // while (row >= 0 && image.Pixels[row, column].BorderType != BorderType.Border.STRONG) // --row; for (; ;) { if (row < 0 || image.Pixels[row, column].BorderType == BorderType.Border.STRONG || (image.Pixels[row, column + 1].BorderType == BorderType.Border.STRONG && image.Pixels[row, column - 1].BorderType == BorderType.Border.STRONG) || (image.Pixels[row, column + 1].BorderType == BorderType.Border.STRONG && image.Pixels[row - 1, column - 1].BorderType == BorderType.Border.STRONG) || (image.Pixels[row, column - 1].BorderType == BorderType.Border.STRONG && image.Pixels[row - 1, column + 1].BorderType == BorderType.Border.STRONG)) break; --row; } if (row >= 0) { int intensityI = 0; int intensityJ = 0; GetNeighboringPixel(comparator, row, column, ref intensityI, ref intensityJ); if (column == intensityJ && intensityI == row + 1) { fillingImage.Pixels[row, column].StrokeWidth.WasProcessed = true; fillingImage.Pixels[rowFrom, column].StrokeWidth.WasProcessed = true; FillColumnWithStrokeWidth(fillingImage, row + 1, rowFrom, column, rowFrom - row - 1); } else { fillingImage.Pixels[rowFrom, column].StrokeWidth.WasProcessed = true; FillColumnWithStrokeWidth(fillingImage, row + 1, rowFrom, column, rowFrom - row - 1); } Ray ray = new Ray(); ray.RowBeginIndex = row + 1; ray.RowEndIndex = rowFrom; ray.ColumnBeginIndex = column; ray.Direction = RayDirection.UP; rays.Add(ray); } } catch (Exception exception) { throw exception; } }
/// <summary> /// Строит луч от пикселя вправо вверх /// </summary> /// <param name="image">Изображение, представляющее границы</param> /// <param name="fillingImage">Изображение для карты SWT</param> /// <param name="comparator">Функция сравнение интенсивностей пикселей</param> /// <param name="row">Номер строки пикселя, от которого строится луч</param> /// <param name="column">Номер столбца пикселя, от которого строится луч</param> private void TrackRayRightUp(GreyImage image, GreyImage fillingImage, List<Ray> rays, CompareIntensity comparator, int row, int column) { try { int imageHeight = image.Height; int imageWidth = image.Width; int columnFrom = column; int rowfrom = row; column += 1; row -= 1; /* while (row >= 0 && column < imageWidth && image.Pixels[row, column].BorderType != BorderType.Border.STRONG && (image.Pixels[row, column].BorderType != BorderType.Border.STRONG)) { --row; ++column; }*/ for (;;) { if (row - 1 < 0 || column + 1 >= imageWidth || image.Pixels[row, column].BorderType == BorderType.Border.STRONG || (image.Pixels[row - 1, column].BorderType == BorderType.Border.STRONG && image.Pixels[row, column + 1].BorderType == BorderType.Border.STRONG)) break; --row; ++column; } if (column + 1 < imageWidth && row - 1 >= 0) { int intensityI = 0; int intensityJ = 0; GetNeighboringPixel(comparator, row, column, ref intensityI, ref intensityJ); if (row == intensityI - 1 && column == intensityJ + 1) { fillingImage.Pixels[row, column].StrokeWidth.WasProcessed = true; fillingImage.Pixels[rowfrom, columnFrom].StrokeWidth.WasProcessed = true; FillDiagonaWithStrokeWidth(fillingImage, row + 1, rowfrom, column - 1, -1, (int) ((rowfrom - row - 1) * Math.Sqrt(2.0))); } else { fillingImage.Pixels[rowfrom, columnFrom].StrokeWidth.WasProcessed = true; FillDiagonaWithStrokeWidth(fillingImage, row + 1, rowfrom, column - 1, -1, (int) ((rowfrom - row - 1) * Math.Sqrt(2.0))); } Ray ray = new Ray(); ray.RowBeginIndex = row + 1; ray.RowEndIndex = rowfrom; ray.ColumnBeginIndex = column - 1; ray.Direction = RayDirection.RIGHT_UP; ray.ColumnStep = -1; rays.Add(ray); } } catch (Exception exception) { throw exception; } }
/// <summary> /// Строит луч от пикселя вправо /// </summary> /// <param name="image">Изображение, представляющее границы</param> /// <param name="fillingImage">Изображение для карты SWT</param> /// <param name="comparator">Функция сравнение интенсивностей пикселей</param> /// <param name="row">Номер строки пикселя, от которого строится луч</param> /// <param name="column">Номер столбца пикселя, от которого строится луч</param> private void TrackRayRight(GreyImage image, GreyImage fillingImage, List<Ray> rays, CompareIntensity comparator, int row, int column) { try { int imageWidth = image.Width; int columnFrom = column; column += 1; while (column < imageWidth && image.Pixels[row, column].BorderType != BorderType.Border.STRONG) ++column; if (column < imageWidth) { int intensityI = 0; int intensityJ = 0; GetNeighboringPixel(comparator, row, column, ref intensityI, ref intensityJ); if (intensityI == row && intensityJ == column - 1) { fillingImage.Pixels[row, column].StrokeWidth.WasProcessed = true; fillingImage.Pixels[row, columnFrom].StrokeWidth.WasProcessed = true; FillRowWithStrokeWidth(fillingImage, columnFrom + 1, column, row, column - columnFrom - 1); } else { fillingImage.Pixels[row, columnFrom].StrokeWidth.WasProcessed = true; FillRowWithStrokeWidth(fillingImage, columnFrom + 1, column, row, column - columnFrom - 1); } Ray ray = new Ray(); ray.ColumnBeginIndex = columnFrom + 1; ray.ColumnEndIndex = column; ray.RowBeginIndex = row; ray.Direction = RayDirection.RIGHT; rays.Add(ray); } } catch (Exception exception) { throw exception; } }
/// <summary> /// Строит луч от пикселя вниз /// </summary> /// <param name="image">Изображение, представляющее границы</param> /// <param name="fillingImage">Изображение для карты SWT</param> /// <param name="comparator">Функция сравнение интенсивностей пикселей</param> /// <param name="row">Номер строки пикселя, от которого строится луч</param> /// <param name="column">Номер столбца пикселя, от которого строится луч</param> private void TrackRayDown(GreyImage image, GreyImage fillingImage, List<Ray> rays, CompareIntensity comparator, int row, int column) { try { int imageHeight = image.Height; int rowFrom = row; row += 1; while (row < imageHeight && image.Pixels[row, column].BorderType != BorderType.Border.STRONG) ++row; if (row < imageHeight) { int intensityI = 0; int intensityJ = 0; GetNeighboringPixel(comparator, row, column, ref intensityI, ref intensityJ); if (column == intensityJ && intensityI == row - 1) { fillingImage.Pixels[row, column].StrokeWidth.WasProcessed = true; fillingImage.Pixels[rowFrom, column].StrokeWidth.WasProcessed = true; FillColumnWithStrokeWidth(fillingImage, rowFrom + 1, row, column, row - rowFrom - 1); } else { fillingImage.Pixels[rowFrom, column].StrokeWidth.WasProcessed = true; FillColumnWithStrokeWidth(fillingImage, rowFrom + 1, row, column, row - rowFrom - 1); } Ray ray = new Ray(); ray.RowBeginIndex = rowFrom + 1; ray.RowEndIndex = row; ray.ColumnBeginIndex = column; ray.Direction = RayDirection.DOWN; rays.Add(ray); } } catch (Exception exception) { throw exception; } }
/// <summary> /// Находит индексы пискеля - соседа с максимальной или миннимальной интенсивнотью в зависимости от comparator /// </summary> /// <param name="comparator">Функция сравнения интенсивностей</param> /// <param name="row">Номер строки текущего пикселя</param> /// <param name="column">Номер столбца текущего пикселя</param> /// <param name="intensityI">Номер строки искомого пикселя</param> /// <param name="intensityJ">Номер столбца искомого пикселя</param> private void GetNeighboringPixel(CompareIntensity comparator, int row, int column, ref int intensityI, ref int intensityJ) { int intensity = _gaussSmoothedImage.Pixels[row - 1, column - 1].Color.Data; intensityI = row - 1; intensityJ = column - 1; if (comparator(intensity, _gaussSmoothedImage.Pixels[row - 1, column].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row - 1, column].Color.Data; intensityI = row - 1; intensityJ = column; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row - 1, column + 1].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row - 1, column + 1].Color.Data; intensityI = row - 1; intensityJ = column + 1; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row, column - 1].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row, column - 1].Color.Data; intensityI = row; intensityJ = column - 1; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row, column + 1].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row, column + 1].Color.Data; intensityI = row; intensityJ = column + 1; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row + 1, column - 1].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row + 1, column - 1].Color.Data; intensityI = row + 1; intensityJ = column - 1; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row + 1, column].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row + 1, column].Color.Data; intensityI = row + 1; intensityJ = column; } if (comparator(intensity, _gaussSmoothedImage.Pixels[row + 1, column + 1].Color.Data)) { intensity = _gaussSmoothedImage.Pixels[row + 1, column + 1].Color.Data; intensityI = row + 1; intensityJ = column + 1; } }
/// <summary> /// Вычисляет карту SWT для изображения /// </summary> /// <param name="image">Изображение, представляющее границы изображения</param> /// <param name="fillingImage">Изображения для заполнения SWT карты</param> /// <param name="comparator">Функция сравнения интенсивностей пикселей</param> private void FillStrokeImage(GreyImage image, GreyImage fillingImage, List<Ray> rays, CompareIntensity comparator) { try { int imageHeight = image.Height - 1; int imageWidth = image.Width - 1; for (int i = 1; i < imageHeight; i++) for (int j = 1; j < imageWidth; j++) { if (image.Pixels[i, j].BorderType == BorderType.Border.STRONG && !fillingImage.Pixels[i, j].StrokeWidth.WasProcessed) { int intensityI = 0; int intensityJ = 0; GetNeighboringPixel(comparator, i, j, ref intensityI, ref intensityJ); if (intensityI == i && intensityJ == j + 1) TrackRayRight(image, fillingImage, rays, comparator, i, j); else if (intensityI == i && intensityJ == j - 1) TrackRayLeft(image, fillingImage, rays, comparator, i, j); else if (intensityJ == j && intensityI == i + 1) TrackRayDown(image, fillingImage, rays, comparator, i, j); else if (intensityJ == j && intensityI == i - 1) TrackRayUp(image, fillingImage, rays, comparator, i, j); else if (intensityI == i - 1 && intensityJ == j + 1) TrackRayRightUp(image, fillingImage, rays, comparator, i, j); else if (intensityI == i + 1 && intensityJ == j + 1) TrackRayRightDown(image, fillingImage, rays, comparator, i, j); else if (intensityI == i - 1 && intensityJ == j - 1) TrackRayLeftUp(image, fillingImage, rays, comparator, i, j); else if (intensityI == i + 1 && intensityJ == j - 1) TrackRayLeftDown(image, fillingImage, rays, comparator, i, j); ; } } } catch (Exception exception) { throw exception; } }