This commit is contained in:
THE_KONDRAT 2025-04-28 21:30:59 +03:00
parent 74e4698c43
commit 2f721d6514
27 changed files with 1047 additions and 516 deletions

View File

@ -0,0 +1,25 @@
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/.idea
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

View File

@ -1,8 +1,8 @@
using Domain.Abstractions;
using SkiaSharp;
namespace Domain;
public class FramePartRenderResult
public class BigFrameLayerRenderResult
{
public uint Row { get; set; }
public uint Column { get; set; }
@ -10,5 +10,6 @@ public class FramePartRenderResult
public uint FrameSizeY { get; set; }
// или пиксели?
public string Frame { get; set; }
public SKBitmap Frame { get; set; } //типа автомаска
public List<ExpIniFileGenerator.FrameExpInfo> FrameInfos { get; set; } = [];
}

View File

@ -1,9 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="SkiaSharp" Version="3.116.1" />
</ItemGroup>
</Project>

View File

@ -1,6 +1,6 @@
using System.Text;
namespace Domain.Something;
namespace Domain;
public class ExpIniFileGenerator(uint rowCount, uint oddColumnCount, uint evenColumnCount)
{

View File

@ -0,0 +1,12 @@
using Domain;
namespace Domain.Interfaces;
public interface IFrameRender
{
public Guid RenderId { get; }
public Task<IEnumerable<ExpIniFileGenerator.FrameExpInfo>> Execute(CancellationToken cancellationToken);
public long EstimateMemoryUsage();
}

View File

@ -1,5 +1,5 @@
using SkiaSharp;
namespace Domain;
namespace Domain.Interfaces;
public interface ILayer
{
@ -9,5 +9,5 @@ public interface ILayer
public SKBitmap? Mask { get; }
public bool InvertMask { get; }
public Task Prerender();
public Task<SKBitmap> Render(uint u, uint u1, uint frameWidth, uint frameHeight, SKBitmap automask);
public Task<SKBitmap> Render(uint x, uint y, uint frameWidth, uint frameHeight, SKBitmap automask);
}

View File

@ -1,4 +1,4 @@
namespace Domain;
namespace Domain.Interfaces;
public interface IRenderManager
{

View File

@ -0,0 +1,10 @@
using Domain.Interfaces;
namespace Domain;
public class Project
{
public Guid Id { get; set; }
public IEnumerable<ILayer> Layers { get; set; } = [];
public uint Width { get; set; }
public uint Height { get; set; }
}

View File

@ -0,0 +1,69 @@
using System.Threading.Channels;
using Domain.Interfaces;
using Domain.RenderPart;
namespace Domain;
public class Render
{
public Guid Id { get; }
public Guid ProjectId { get; }
private readonly IEnumerable<ILayer> _layers;
private readonly uint _width;
private readonly uint _height;
private readonly bool _useBigFrames = true;
private readonly CancellationTokenSource _cancellationTokenSource = new();
public Render(Project project)
{
Id = Guid.NewGuid();
ProjectId = project.Id;
_width = project.Width;
_height = project.Height;
_layers = project.Layers;
}
public async Task Run(Channel<IFrameRender> channel)
{
foreach (var layer in _layers)
{
await layer.Prerender();
}
if (_useBigFrames)
{
await MakeBigFrames(channel);
}
else
{
throw new NotImplementedException();
// MakeFrames(channel);
}
//maybe returb render result
}
private async Task MakeBigFrames(Channel<IFrameRender> channel)
{
uint bigFrameWidth = 8, bigFrameHeight = 8;
for (uint y = 0; y < _height; y += bigFrameHeight)
{
uint currentBigFrameHeight = Math.Min(bigFrameHeight, _height - y);
for (uint x = 0; x < _width; x += bigFrameWidth)
{
uint currentBigFrameWidth = Math.Min(bigFrameWidth, _width - x);
var bigFrameRender = new BigFrameRender(_layers, x, y, currentBigFrameWidth, currentBigFrameHeight, Id);
await channel.Writer.WriteAsync(bigFrameRender);
}
}
}
public async Task Stop()
{
await Task.Delay(100);
}
}

View File

@ -0,0 +1,89 @@
using System.Collections.Concurrent;
using System.Threading.Channels;
using Domain.Interfaces;
namespace Domain;
public class RenderManager : IRenderManager
{
private readonly Channel<IFrameRender> _taskChannel;
private readonly ConcurrentDictionary<Guid, Render> _renders = [];
public RenderManager(int channelCapacity = 5)
{
var options = new BoundedChannelOptions(channelCapacity)
{
FullMode = BoundedChannelFullMode.Wait // Ожидание при переполнении канала
};
_taskChannel = Channel.CreateBounded<IFrameRender>(options);
}
public Task<Guid> StartRender(Project project)
{
var render = new Render(project);
if (_renders.TryAdd(render.Id, render))
{
_ =render.Run(_taskChannel);
}
_ = ProcessQueue();
return Task.FromResult(render.Id);
}
private async Task ProcessQueue(CancellationToken cancellationToken = default)
{
while (await _taskChannel.Reader.WaitToReadAsync(cancellationToken))
{
while (_taskChannel.Reader.TryRead(out var task))
{
try
{
await task.Execute(cancellationToken);
}
catch (OperationCanceledException)
{
// Console.WriteLine($"Task {task.RenderId} was cancelled.");
}
}
}
}
public async Task StopRender(Guid renderId)
{
if (_renders.TryRemove(renderId, out var render))
{
await render.Stop();
UpdateProjectHistoryToHistory(render.ProjectId, render.Id);
}
}
private async Task ClearTasksForRender(Guid renderId)
{
var remainingTasks = new List<IFrameRender>();
while (await _taskChannel.Reader.WaitToReadAsync())
{
if (_taskChannel.Reader.TryRead(out var task))
{
// if (task.RenderId != renderId)
// {
// remainingTasks.Add(task);
// }
}
}
foreach (var task in remainingTasks)
{
await _taskChannel.Writer.WriteAsync(task);
}
}
private void UpdateProjectHistoryToHistory(Guid projectId, Guid renderId)
{
Console.WriteLine($"UpdateProjectHistoryToHistory: {projectId}, {renderId}");
}
public IEnumerable<Guid> GetActiveRenders()
{
return new List<Guid>();
}
}

View File

@ -1,9 +1,7 @@
using Domain.Abstractions;
using Domain.Interfaces;
using Domain.Something;
using SkiaSharp;
namespace Domain;
namespace Domain.RenderPart;
public class BigFrameRender : RenderPartBase
{

View File

@ -1,6 +1,6 @@
namespace Domain.RenderPart;
// public class FrameRenderPart : RenderPartBase
// public class FrameRender : RenderPartBase
// {
//
// }

View File

@ -1,9 +1,6 @@
using System.Collections;
using Domain.Abstractions;
using Domain.Interfaces;
using Domain.Something;
namespace Domain;
namespace Domain.RenderPart;
public abstract class RenderPartBase : IFrameRender
{

View File

@ -1,6 +1,29 @@
namespace Domain.Abstractions;
namespace Domain;
public class RenderResult
{
public List<>
public List<FrameInfo> Frames { get; set; } = [];
public ExpIniConfig ExpIniConfig { get; set; } = null!;
}
public class ExpIniConfig
{
public uint RowCount { get; set; }
public uint OddColumnCount { get; set; }
public uint EvenColumnCount { get; set; }
public IEnumerable<ExpIniFileGenerator.FrameExpInfo> FrameInfos { get; set; } = [];
}
public class FrameInfo
{
public uint Number { get; set; }
public uint Row { get; set; }
public uint Column { get; set; }
public ExpState State { get; set; }
}
public enum ExpState
{
E, //поправить
Z, //поправить
}

View File

@ -0,0 +1,39 @@
syntax = "proto3";
import "google/protobuf/wrappers.proto";
option csharp_namespace = "LayerClients";
service TestLayer {
rpc Prerender (PrerenderRequest) returns (PrerenderResponse);
rpc Render (RenderRequest) returns (RenderResponse);
}
message PrerenderRequest {
string optical_schema_data = 1;
bytes mask = 2;
bytes image = 3;
bool invert_mask = 4;
}
message PrerenderResponse {
string status = 1;
repeated MatrixRow test_matrix = 2; // Представляем матрицу через строки
}
message MatrixRow {
repeated double values = 1; // Значения одной строки матрицы
}
message RenderRequest {
uint32 x = 1;
uint32 y = 2;
uint32 frame_width = 3;
uint32 frame_height = 4;
bytes image = 5;
google.protobuf.BoolValue invert_mask = 6;
google.protobuf.BytesValue mask = 7;
google.protobuf.BytesValue automask = 8;
}
message RenderResponse {
bytes rendered_image = 1;
}

View File

@ -0,0 +1,62 @@
using Domain;
using Domain.Interfaces;
using Google.Protobuf;
using LayerClients;
using SkiaSharp;
namespace Make3.RenderServer.Layers;
public class TestLayer(LayerClients.TestLayer.TestLayerClient grpcClient) : ILayer
{
public uint Order { get; init; }
public OpticalSchema OpticalSchema { get; init; }
public SKBitmap? Mask { get; init; }
public required SKBitmap Image { get; init; }
public bool InvertMask { get; init; }
private readonly LayerClients.TestLayer.TestLayerClient _grpcClient = grpcClient;
public async Task Prerender()
{
using var imageData = Image.Encode(SKEncodedImageFormat.Png, 100);
using var maskData = Mask?.Encode(SKEncodedImageFormat.Png, 100);
var request = new PrerenderRequest
{
OpticalSchemaData = OpticalSchema.ToString(),
Image = ByteString.CopyFrom(imageData.Span),
};
if (maskData != null)
{
request.Mask = ByteString.CopyFrom(maskData.Span);
request.InvertMask = InvertMask;
}
var response = await _grpcClient.PrerenderAsync(request);
}
public async Task<SKBitmap> Render(uint x, uint y, uint frameWidth, uint frameHeight, SKBitmap? automask)
{
//здесь надо кусок изображения взять
using var imageData = Image.Encode(SKEncodedImageFormat.Png, 100);
using var maskData = Mask?.Encode(SKEncodedImageFormat.Png, 100);
using var automaskData = automask?.Encode(SKEncodedImageFormat.Png, 100);
var request = new RenderRequest
{
X = x,
Y = y,
FrameWidth = frameWidth,
FrameHeight = frameHeight,
Image = ByteString.CopyFrom(imageData.Span),
// Automask = ByteString.CopyFrom(imageData.Span),
};
if (maskData != null)
{
request.Mask = ByteString.CopyFrom(maskData.Span);
request.InvertMask = InvertMask;
}
request.Automask = automaskData == null ? null : ByteString.CopyFrom(automaskData.Span);
var response = await _grpcClient.RenderAsync(request);
var byteArray = response.RenderedImage.ToByteArray();
return SKBitmap.Decode(byteArray);
}
}

View File

@ -8,6 +8,11 @@
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.71.0" />
<PackageReference Include="Grpc.Tools" Version="2.71.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.4"/>
</ItemGroup>
@ -17,4 +22,12 @@
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="Grpc\Protos\Layers\test-layer.proto" GrpcServices="Client"/>
</ItemGroup>
</Project>

View File

@ -1,9 +1,23 @@
using Domain;
using Domain.Interfaces;
using Make3.RenderServer;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddScoped<IRenderManager, RenderManager>();
// builder.Services.AddGrpc();
builder.Services.AddGrpcClient<LayerClients.TestLayer.TestLayerClient>(options =>
{
options.Address = new Uri("http://localhost:5062");
});
builder.Services.AddHostedService<TestProjectBackgroundService>();
var app = builder.Build();
// Configure the HTTP request pipeline.

View File

@ -0,0 +1,61 @@
using Domain;
using Domain.Interfaces;
using Make3.RenderServer.Layers;
using SkiaSharp;
namespace Make3.RenderServer;
public class TestProjectBackgroundService : BackgroundService
{
private readonly IServiceProvider _serviceProvider;
private readonly LayerClients.TestLayer.TestLayerClient _testLaterGrpcClient;
public TestProjectBackgroundService(IServiceProvider serviceProvider, LayerClients.TestLayer.TestLayerClient testLaterGrpcClient)
{
_serviceProvider = serviceProvider;
_testLaterGrpcClient = testLaterGrpcClient;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
var dir = @"C:\Users\Ko12A\OneDrive\Изображения";
var image1 = OpenImage(Path.Combine(dir, "01_gettyimages_488111026_resized.jpg"));
var image2 = OpenImage(Path.Combine(dir, "kisspng-bmp-file-for.bmp"));
var image3 = OpenImage(Path.Combine(dir, "Zrzut ekranu 2021-07-20 164131.png"));
var project = new Project
{
Id = Guid.NewGuid(),
Height = Convert.ToUInt32(image1.Width),
Width = Convert.ToUInt32(image2.Width),
Layers = [
new TestLayer(_testLaterGrpcClient)
{
Order = 0,
Image = image1,
OpticalSchema = OpticalSchema.Sp11,
},
new TestLayer(_testLaterGrpcClient)
{
Order = 1,
Image = image2,
Mask = image3,
InvertMask = false,
OpticalSchema = OpticalSchema.Sp11,
},
],
};
using var scope = _serviceProvider.CreateScope();
var renderManager = scope.ServiceProvider.GetRequiredService<IRenderManager>();
var renderId = await renderManager.StartRender(project);
}
private SKBitmap OpenImage(string filename)
{
using SKBitmap bitmap = SKBitmap.Decode(filename);
return bitmap.Copy();
}
}

View File

@ -7,6 +7,13 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Make3.Renderer", "Make3.Ren
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Domain", "Domain\Domain.csproj", "{5D88EEB2-A075-4531-890E-DC38E2700325}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FA217554-E89C-467E-AE89-FC167D77F55F}"
ProjectSection(SolutionItems) = preProject
compose.yaml = compose.yaml
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Make3.RenderServer", "Make3.RenderServer\Make3.RenderServer.csproj", "{3262E7F2-74E7-4314-A87B-E8CC357CCE76}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -21,6 +28,10 @@ Global
{5D88EEB2-A075-4531-890E-DC38E2700325}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5D88EEB2-A075-4531-890E-DC38E2700325}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5D88EEB2-A075-4531-890E-DC38E2700325}.Release|Any CPU.Build.0 = Release|Any CPU
{3262E7F2-74E7-4314-A87B-E8CC357CCE76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3262E7F2-74E7-4314-A87B-E8CC357CCE76}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3262E7F2-74E7-4314-A87B-E8CC357CCE76}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3262E7F2-74E7-4314-A87B-E8CC357CCE76}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -1,17 +1,29 @@
using Domain.Abstractions;
using Domain;
using Domain.Interfaces;
using SkiaSharp;
namespace Domain.ConcreteLayers;
namespace Make3.Renderer;
public class Layer1 : ILayer
{
public uint Order { get; set; }
public OpticalSchema OpticalSchema { get; set; }
public char[,] Image { get; set; }
public char[,]? Mask { get; set; }
public SKBitmap Image { get; set; }
public SKBitmap? Mask { get; set; }
public bool InvertMask { get; set; }
public Task Execute()
{
throw new NotImplementedException();
}
public async Task Prerender()
{
throw new NotImplementedException();
}
public async Task<SKBitmap> Render(uint x, uint y, uint frameWidth, uint frameHeight, SKBitmap automask)
{
throw new NotImplementedException();
}
}

View File

@ -2,18 +2,26 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13</LangVersion>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="OpenCvSharp4" Version="4.8.0.20230708" />
<PackageReference Include="OpenCvSharp4.runtime.win" Version="4.8.0.20230708" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Domain\Domain.csproj" />
</ItemGroup>
<ItemGroup>
<None Update="test1.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="test2.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="test2-mask.txt">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,46 +1,64 @@
// See https://aka.ms/new-console-template for more information
using Domain.Abstractions;
using Make3.Renderer;
using Make3.Renderer.Layers.TrekoLayers;
using OpenCvSharp;
Console.WriteLine("Hello, World!");
using Domain;
using SkiaSharp;
var filePath = @"F:\GS_TEST.png";
filePath = @"F:\GS_TEST_1.png";
var outputDirectory = "F:\\";
using (var s = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
var testClass = new TestClass(s, outputDirectory);
testClass.Execute();
}
Console.ReadLine();
//входные данные
var projectLayers = new List<ILayer>
{
new Treko(0),
new Treko(1),
new Treko(2),
};
//программа
projectLayers.Sort((a, b) => a.Order.CompareTo(b.Order));
for (int i = 0; i < projectLayers.Count; i++)
{
await projectLayers[i].Execute();
}
//List<ushort> ImageColors(Mat image)
// SKBitmap OpenImage(string filename)
// {
// var text = File.ReadAllText(filename);
// var rows = text.Split(Environment.NewLine);
// var width = rows.Max(q => q.Length);
// var result = new char[width, rows.Length];
// for (var row = 0; row < rows.Length; row++)
// {
// for (var col = 0; col < width; col++)
// {
// result[col, row] = rows[row][col];
// }
// }
// return result;
// }
class ShapeInfo
{
public Point[][] Points { get; set; }
public byte Color { get; set; }
}
// var filePath = @"F:\GS_TEST.png";
// filePath = @"F:\GS_TEST_1.png";
//
// var outputDirectory = "F:\\";
//
// using (var s = new FileStream(filePath, FileMode.Open, FileAccess.Read))
// {
// var testClass = new TestClass(s, outputDirectory);
// testClass.Execute();
// }
// Console.ReadLine();
// //входные данные
// var projectLayers = new List<ILayer>
// {
// new Treko(0),
// new Treko(1),
// new Treko(2),
// };
//
//
// //программа
// projectLayers.Sort((a, b) => a.Order.CompareTo(b.Order));
//
// for (int i = 0; i < projectLayers.Count; i++)
// {
// await projectLayers[i].Execute();
// }
//
// //List<ushort> ImageColors(Mat image)
// //{
//
// //}
//
// class ShapeInfo
// {
// public Point[][] Points { get; set; }
// public byte Color { get; set; }
// }

View File

@ -1,425 +1,425 @@
using OpenCvSharp;
namespace Make3.Renderer
{
internal class TestClass
{
private readonly Mat _inputMat;
private readonly string _outputDirectory;
public TestClass(Stream stream, string outputDirectory)
{
_inputMat = Mat.FromStream(stream, ImreadModes.Grayscale); ;
_outputDirectory = outputDirectory;
}
public TestClass(Mat inputMat, string outputDirectory)
{
_inputMat = inputMat;
_outputDirectory = outputDirectory;
}
internal void Execute()
{
var colors = GetColors();
var c = _inputMat.Threshold(0, 255, ThresholdTypes.Binary & ThresholdTypes.Otsu);
var closing = c.EmptyClone();
Cv2.MorphologyEx(c, closing, MorphTypes.Close, null);
//var contours0 = closing.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
Point[][] contours;
HierarchyIndex[] hierarchy;
//closing.FindContours(out contours1, , RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
closing.FindContours(out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
var contNum = 0;
var allContursColored = GetContoursColored(contours, hierarchy, contNum);
allContursColored.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST_{contNum}_conturs_colored.png"));
var allConturs = GetContoursBW(contours, hierarchy, contNum);
allConturs.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contNum}_conturs_BW.png"));
//colorSeparatedMats.Add(c);
DistanceTransform(allConturs, contNum);
}
private List<ushort> GetColors()
{
var nonZero = _inputMat.FindNonZero();
var colors = new List<ushort>();
var total = nonZero.Total();
for (int i = 0; i < total; i++)
{
var p = nonZero.At<Point>(i);
var color = _inputMat.At<byte>(p.X, p.Y);
if (!colors.Contains(color) && color != 0) colors.Add(color);
}
return colors;
}
private Mat GetContoursColored(Point[][] contours, HierarchyIndex[] hierarchy, int contur)
{
var result = Mat.Zeros(_inputMat.Size(), MatType.CV_8UC3).ToMat();
Cv2.DrawContours(result, contours, contur, new Scalar(hierarchy[contur].Parent < 0 ? 255 : 0, 128, 20 * contur), -1,
hierarchy: hierarchy,
maxLevel: int.MaxValue);
return result;
}
/// <summary>
/// sdfsd
/// </summary>
/// <param name="contours"></param>
/// <param name="hierarchy"></param>
/// <param name="contur"></param>
/// <returns></returns>
private Mat GetContoursBW(Point[][] contours, HierarchyIndex[] hierarchy, int contur)
{
var result = Mat.Zeros(_inputMat.Size(), MatType.CV_8UC1).ToMat();
Cv2.DrawContours(result, contours, contur, new Scalar(hierarchy[contur].Parent < 255 ? 255 : 20 * contur), -1,
hierarchy: hierarchy,
maxLevel: int.MaxValue);
return result;
}
/// <summary>
/// <para>
/// Ссылка на обсуждение нахождения расстояний
/// <see href="https://stackoverflow.com/questions/26421566/pixel-indexing-in-opencvs-distance-transform">вот</see> и на форум из комментариев
/// <see href="https://answers.opencv.org/question/6109/per-pixel-labeling-in-distancetransform/">ещё вот</see>. Там на C++
/// </para>
/// <para>
/// Вот ещё <see href="https://docs.opencv.org/3.4/d2/dbd/tutorial_distance_transform.html">что-то</see> с DataTransform.
/// </para>
/// <para>
/// И ещё, но <see href="https://www.reddit.com/r/computervision/comments/cj7kqq/any_algorithms_for_finding_closest_two_black/">что-то</see> не читал.
/// </para>
/// <para>
/// <see href="https://www.appsloveworld.com/opencv/100/6/pixel-indexing-in-opencvs-distance-transform">Это</see>, к сожалению, на Питоне,
/// и там используется местная библиотека numpy, так что не подходит.
/// </para>
/// <para>
/// Вот <see href="https://python.hotexamples.com/ru/examples/cv2/-/distanceTransformWithLabels/python-distancetransformwithlabels-function-examples.html">тут</see>
/// примеры функций типа bwdist и прочих. До конца не смотрел, возможно, что-то и подходит.К сожалению, тоже на Питоне, и также используется numpy.
/// </para>
/// <para>
/// <see href="https://shimat.github.io/opencvsharp_docs/html/f61ce7b7-e1a6-119d-9a73-3d60751e88de.htm">Это</see>
/// просто документация, описание DistanceTransformWithLabels. К сожалению, написано очень скудно, и примеров нет.
/// </para>
/// <para>
/// Вот <see href="https://csharpdoc.hotexamples.com/class/OpenCvSharp/Cv2">тут</see>
/// примеры функций, но похоже, просто скопировано с докементации, примеров, к сожалению, нет (ну они есть, но <see href="https://csharp.hotexamples.com/examples/OpenCvSharp/Cv2/-/php-cv2-class-examples.html">не те</see>).
/// </para>
/// </summary>
/// <param name="input"></param>
/// <param name="contur"></param>
private void DistanceTransform(Mat input, int contur)
{
var distanceTransform = input.EmptyClone();
//Cv2.DistanceTransform(dst1, dst2, DistanceTypes.L2, DistanceTransformMasks.Precise);
var labels = input.EmptyClone();
Cv2.DistanceTransformWithLabels(input, distanceTransform, labels, DistanceTypes.L2, DistanceTransformMasks.Precise,
//Cv2.DistanceTransformWithLabels(dst1, dst2, labelIndexes, DistanceTypes.L2, DistanceTransformMasks.Mask3,
DistanceTransformLabelTypes.Pixel);
distanceTransform.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contur}_distance_transform.png"));
//labels.PushBack(-1);
var k = 1;
for (int i = 0; i < distanceTransform.Height; i++)
{
for (int j = 0; j < distanceTransform.Width; j++)
{
var px = distanceTransform.At<int>(i, j);
if (px == 0)
{
//labels.PushBack(new Vec2i(i, j));
}
else { }
var p = labels.At<int>(i, j);
var p_x = p % labels.Width;
var p_y = p / labels.Width;
var p1 = labels.At<Vec2i>(i, j);
var p2 = labels.At<Vec3i>(i, j);
var p3 = labels.At<Point2d>(i, j);
var p4 = labels.At<Point>(i, j);
}
}
labels.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contur}_distance_transform_labels.png"));
}
//private void B()
// using OpenCvSharp;
//
// namespace Make3.Renderer
// {
// using (var s = new FileStream(filePath, FileMode.Open, FileAccess.Read))
// internal class TestClass
// {
// //var m = new Mat();
// //var m = Mat.FromStream(s, ImreadModes.Color);
// var m = Mat.FromStream(s, ImreadModes.Grayscale);
// var result = new List<ushort>();
// var nonZero = m.FindNonZero();
// private readonly Mat _inputMat;
// private readonly string _outputDirectory;
//
// public TestClass(Stream stream, string outputDirectory)
// {
// _inputMat = Mat.FromStream(stream, ImreadModes.Grayscale); ;
// _outputDirectory = outputDirectory;
// }
//
// public TestClass(Mat inputMat, string outputDirectory)
// {
// _inputMat = inputMat;
// _outputDirectory = outputDirectory;
// }
//
// internal void Execute()
// {
// var colors = GetColors();
//
// var c = _inputMat.Threshold(0, 255, ThresholdTypes.Binary & ThresholdTypes.Otsu);
// var closing = c.EmptyClone();
// Cv2.MorphologyEx(c, closing, MorphTypes.Close, null);
//
// //var contours0 = closing.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// Point[][] contours;
// HierarchyIndex[] hierarchy;
// //closing.FindContours(out contours1, , RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// closing.FindContours(out contours, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
//
// var contNum = 0;
//
// var allContursColored = GetContoursColored(contours, hierarchy, contNum);
// allContursColored.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST_{contNum}_conturs_colored.png"));
//
// var allConturs = GetContoursBW(contours, hierarchy, contNum);
// allConturs.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contNum}_conturs_BW.png"));
//
// //colorSeparatedMats.Add(c);
//
// DistanceTransform(allConturs, contNum);
// }
//
// private List<ushort> GetColors()
// {
// var nonZero = _inputMat.FindNonZero();
// var colors = new List<ushort>();
// var total = nonZero.Total();
// for (int i = 0; i < total; i++)
// {
// var p = nonZero.At<Point>(i);
// var color = m.At<byte>(p.X, p.Y);
// var color = _inputMat.At<byte>(p.X, p.Y);
// if (!colors.Contains(color) && color != 0) colors.Add(color);
// }
// //___
// //var c = m.InRange(new Scalar(color), new Scalar(color));
// var c = m.Threshold(0, 255, ThresholdTypes.Binary & ThresholdTypes.Otsu);
// var closing = c.EmptyClone();
// //var contours0 = closing.FindContoursAsMat(RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// //Cv2.MorphologyEx(c, closing, MorphTypes.Close, contours0[0]);
// Cv2.MorphologyEx(c, closing, MorphTypes.Close, null);
// //var contours0 = closing.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// Point[][] contours1;
// HierarchyIndex[] hierarchy;
// //closing.FindContours(out contours1, , RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// closing.FindContours(out contours1, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// var contNum = 0;
// var aaaaa = contours1.Count();
// var aaa = hierarchy.Where(q => q.Parent < 0).ToList();
// //var boundingRect = Cv2.BoundingRect(contours1[0]);
// var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// //Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, 128, 20 * contNum), -1,
// // LineTypes.Link8, maxLevel: -1);
// //Cv2.DrawContours(dst0, contours1, 0, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1, maxLevel: -1);
// //Cv2.DrawContours(dst0, contours1, 0, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1, maxLevel: int.MaxValue);
// Cv2.DrawContours(dst0, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// return colors;
// }
//
// private Mat GetContoursColored(Point[][] contours, HierarchyIndex[] hierarchy, int contur)
// {
// var result = Mat.Zeros(_inputMat.Size(), MatType.CV_8UC3).ToMat();
// Cv2.DrawContours(result, contours, contur, new Scalar(hierarchy[contur].Parent < 0 ? 255 : 0, 128, 20 * contur), -1,
// hierarchy: hierarchy,
// //maxLevel: -1);
// maxLevel: int.MaxValue);
// //colorSeparatedMats.Add(c);
// dst0.SaveImage(@$"F:\GS_TEST_c{contNum}.png");
// var boundingRect = Cv2.BoundingRect(contours1[0]);
// //var dst1 = Mat.Zeros(boundingRect.Size, MatType.CV_8UC1).ToMat();
// var dst1 = Mat.Zeros(m.Size(), MatType.CV_8UC1).ToMat();
// //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// //Cv2.DrawContours(dst1, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// Cv2.DrawContours(dst1, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 255 ? 255 : 20 * contNum), -1,
// return result;
// }
//
// /// <summary>
// /// sdfsd
// /// </summary>
// /// <param name="contours"></param>
// /// <param name="hierarchy"></param>
// /// <param name="contur"></param>
// /// <returns></returns>
// private Mat GetContoursBW(Point[][] contours, HierarchyIndex[] hierarchy, int contur)
// {
// var result = Mat.Zeros(_inputMat.Size(), MatType.CV_8UC1).ToMat();
// Cv2.DrawContours(result, contours, contur, new Scalar(hierarchy[contur].Parent < 255 ? 255 : 20 * contur), -1,
// hierarchy: hierarchy,
// //maxLevel: -1);
// maxLevel: int.MaxValue);
// //colorSeparatedMats.Add(c);
// dst1.SaveImage(@$"F:\GS_TEST_cc{contNum}.png");
// var dst2 = dst1.EmptyClone();
// return result;
// }
//
// /// <summary>
// /// <para>
// /// Ссылка на обсуждение нахождения расстояний
// /// <see href="https://stackoverflow.com/questions/26421566/pixel-indexing-in-opencvs-distance-transform">вот</see> и на форум из комментариев
// /// <see href="https://answers.opencv.org/question/6109/per-pixel-labeling-in-distancetransform/">ещё вот</see>. Там на C++
// /// </para>
// /// <para>
// /// Вот ещё <see href="https://docs.opencv.org/3.4/d2/dbd/tutorial_distance_transform.html">что-то</see> с DataTransform.
// /// </para>
// /// <para>
// /// И ещё, но <see href="https://www.reddit.com/r/computervision/comments/cj7kqq/any_algorithms_for_finding_closest_two_black/">что-то</see> не читал.
// /// </para>
// /// <para>
// /// <see href="https://www.appsloveworld.com/opencv/100/6/pixel-indexing-in-opencvs-distance-transform">Это</see>, к сожалению, на Питоне,
// /// и там используется местная библиотека numpy, так что не подходит.
// /// </para>
// /// <para>
// /// Вот <see href="https://python.hotexamples.com/ru/examples/cv2/-/distanceTransformWithLabels/python-distancetransformwithlabels-function-examples.html">тут</see>
// /// примеры функций типа bwdist и прочих. До конца не смотрел, возможно, что-то и подходит.К сожалению, тоже на Питоне, и также используется numpy.
// /// </para>
// /// <para>
// /// <see href="https://shimat.github.io/opencvsharp_docs/html/f61ce7b7-e1a6-119d-9a73-3d60751e88de.htm">Это</see>
// /// просто документация, описание DistanceTransformWithLabels. К сожалению, написано очень скудно, и примеров нет.
// /// </para>
// /// <para>
// /// Вот <see href="https://csharpdoc.hotexamples.com/class/OpenCvSharp/Cv2">тут</see>
// /// примеры функций, но похоже, просто скопировано с докементации, примеров, к сожалению, нет (ну они есть, но <see href="https://csharp.hotexamples.com/examples/OpenCvSharp/Cv2/-/php-cv2-class-examples.html">не те</see>).
// /// </para>
// /// </summary>
// /// <param name="input"></param>
// /// <param name="contur"></param>
// private void DistanceTransform(Mat input, int contur)
// {
// var distanceTransform = input.EmptyClone();
// //Cv2.DistanceTransform(dst1, dst2, DistanceTypes.L2, DistanceTransformMasks.Precise);
// var labels = dst1.EmptyClone();
// Cv2.DistanceTransformWithLabels(dst1, dst2, labels, DistanceTypes.L2, DistanceTransformMasks.Precise,
// var labels = input.EmptyClone();
// Cv2.DistanceTransformWithLabels(input, distanceTransform, labels, DistanceTypes.L2, DistanceTransformMasks.Precise,
// //Cv2.DistanceTransformWithLabels(dst1, dst2, labelIndexes, DistanceTypes.L2, DistanceTransformMasks.Mask3,
// DistanceTransformLabelTypes.Pixel);
// dst2.SaveImage(@$"F:\GS_TEST_ccc{contNum}.png");
// distanceTransform.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contur}_distance_transform.png"));
//
// //labels.PushBack(-1);
// var k = 1;
// for (int i = 0; i < dst2.Height; i++)
// //for (int i = boundingRect.Top; i < boundingRect.Height; i++)
// for (int i = 0; i < distanceTransform.Height; i++)
// {
// for (int j = 0; j < dst2.Width; j++)
// //for (int j = boundingRect.Left; j < boundingRect.Width; j++)
// for (int j = 0; j < distanceTransform.Width; j++)
// {
// var px = dst2.At<int>(i, j);
// var px = distanceTransform.At<int>(i, j);
// if (px == 0)
// {
// //labels.PushBack(new Vec2i(i, j));
// }
// else { }
// var p = labels.At<int>(i, j);
//
// var p_x = p % labels.Width;
// var p_y = p / labels.Width;
//
// var p1 = labels.At<Vec2i>(i, j);
// var p2 = labels.At<Vec3i>(i, j);
// var p3 = labels.At<Point2d>(i, j);
// var p4 = labels.At<Point>(i, j);
//
// }
// }
// labels.SaveImage(@$"F:\GS_TEST_cccc{contNum}.png");
// //var un = labels.dis
// Console.ReadLine();
// //foreach (var contour in contours1)
//
// labels.SaveImage(Path.Combine(_outputDirectory, $"GS_TEST{contur}_distance_transform_labels.png"));
// }
//
// //private void B()
// //{
// // //if (hierarchy[contNum].Parent < 0)
// // //{
// // // var boundingRect = Cv2.BoundingRect(contour);
// // // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, color, 20 * cNum), -1,
// // // LineTypes.Link8, maxLevel: -1);
// // // //colorSeparatedMats.Add(c);
// // // dst0.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// // //}
// // var boundingRect = Cv2.BoundingRect(contour);
// // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // //Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, 128, 20 * contNum), -1,
// // // LineTypes.Link8, maxLevel: -1);
// // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// // LineTypes.Link8, maxLevel: -1);
// // //colorSeparatedMats.Add(c);
// // dst0.SaveImage(@$"F:\GS_TEST_c{contNum}.png");
// // //var mean = Cv2.Mean(c, mask);
// // //var notBlackContour = Cv2.Mean(c, mask)[0] > 0;
// // //var averageInsideColor =
// // //var c1 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // //var dst0 = c1.EmptyClone();
// // //Cv2.BitwiseAnd(c1, c1, dst0, c.GetRectSubPix(boundingRect.Size, new Point2f(boundingRect.Left + (boundingRect.Width / 2), boundingRect.Top + (boundingRect.Height / 2))));
// // //var c1 = c.CvtColor(ColorConversionCodes.GRAY2BGR);
// // //var m1 = c1.InRange(new Scalar(0), new Scalar(255));
// // //Cv2.FloodFill(c1, m1, new Point(0, 0), new Scalar(0, color, 20 * cNum));
// // //dst0.SaveImage(@$"F:\GS_TEST_cc{cNum}_{contNum}.png");
// // contNum++;
// // using (var s = new FileStream(filePath, FileMode.Open, FileAccess.Read))
// // {
//
// // //var m = new Mat();
// // //var m = Mat.FromStream(s, ImreadModes.Color);
// // var m = Mat.FromStream(s, ImreadModes.Grayscale);
// // var result = new List<ushort>();
//
// // var nonZero = m.FindNonZero();
// // var colors = new List<ushort>();
// // var total = nonZero.Total();
// // for (int i = 0; i < total; i++)
// // {
// // var p = nonZero.At<Point>(i);
// // var color = m.At<byte>(p.X, p.Y);
// // if (!colors.Contains(color) && color != 0) colors.Add(color);
// // }
// //___
// //var colorSeparatedMats = new List<Mat>();
// //var cNum = 0;
// //foreach (var color in colors)
// //{
//
//
// // //___
//
// // //var c = m.InRange(new Scalar(color), new Scalar(color));
//
// // var c = m.Threshold(0, 255, ThresholdTypes.Binary & ThresholdTypes.Otsu);
//
// // var closing = c.EmptyClone();
//
// // //var contours0 = closing.FindContoursAsMat(RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// // //Cv2.MorphologyEx(c, closing, MorphTypes.Close, contours0[0]);
// // Cv2.MorphologyEx(c, closing, MorphTypes.Close, null);
//
// // //var contours0 = closing.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// // Point[][] contours1;
// // HierarchyIndex[] hierarchy;
// // //closing.FindContours(out contours1, , RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// // closing.FindContours(out contours1, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
//
// // var contNum = 0;
//
// // var aaaaa = contours1.Count();
// // var a01 = hierarchy[0].Previous;
// // var a02 = hierarchy[0].Next;
// // var a03 = hierarchy[1].Previous;
// // var a04 = hierarchy[1].Next;
//
// // var aaa = hierarchy.Where(q => q.Parent < 0).ToList();
// // foreach (var contour in contours1)
//
// // //var boundingRect = Cv2.BoundingRect(contours1[0]);
//
// // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // //Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, 128, 20 * contNum), -1,
// // // LineTypes.Link8, maxLevel: -1);
// // //Cv2.DrawContours(dst0, contours1, 0, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1, maxLevel: -1);
// // //Cv2.DrawContours(dst0, contours1, 0, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1, maxLevel: int.MaxValue);
// // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// // hierarchy: hierarchy,
// // //maxLevel: -1);
// // maxLevel: int.MaxValue);
// // //colorSeparatedMats.Add(c);
// // dst0.SaveImage(@$"F:\GS_TEST_c{contNum}.png");
//
// // var boundingRect = Cv2.BoundingRect(contours1[0]);
//
// // //var dst1 = Mat.Zeros(boundingRect.Size, MatType.CV_8UC1).ToMat();
// // var dst1 = Mat.Zeros(m.Size(), MatType.CV_8UC1).ToMat();
// // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // //Cv2.DrawContours(dst1, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// // Cv2.DrawContours(dst1, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 255 ? 255 : 20 * contNum), -1,
// // hierarchy: hierarchy,
// // //maxLevel: -1);
// // maxLevel: int.MaxValue);
// // //colorSeparatedMats.Add(c);
// // dst1.SaveImage(@$"F:\GS_TEST_cc{contNum}.png");
//
// // var dst2 = dst1.EmptyClone();
// // //Cv2.DistanceTransform(dst1, dst2, DistanceTypes.L2, DistanceTransformMasks.Precise);
// // var labels = dst1.EmptyClone();
// // Cv2.DistanceTransformWithLabels(dst1, dst2, labels, DistanceTypes.L2, DistanceTransformMasks.Precise,
// // //Cv2.DistanceTransformWithLabels(dst1, dst2, labelIndexes, DistanceTypes.L2, DistanceTransformMasks.Mask3,
// // DistanceTransformLabelTypes.Pixel);
// // dst2.SaveImage(@$"F:\GS_TEST_ccc{contNum}.png");
//
// // //labels.PushBack(-1);
// // var k = 1;
// // for (int i = 0; i < dst2.Height; i++)
// // //for (int i = boundingRect.Top; i < boundingRect.Height; i++)
// // {
// // //if (hierarchy[contNum].Parent < 0)
// // for (int j = 0; j < dst2.Width; j++)
// // //for (int j = boundingRect.Left; j < boundingRect.Width; j++)
// // {
// // var px = dst2.At<int>(i, j);
// // if (px == 0)
// // {
// // //labels.PushBack(new Vec2i(i, j));
// // }
// // else { }
// // var p = labels.At<int>(i, j);
//
// // var p_x = p % labels.Width;
// // var p_y = p / labels.Width;
//
// // var p1 = labels.At<Vec2i>(i, j);
// // var p2 = labels.At<Vec3i>(i, j);
// // var p3 = labels.At<Point2d>(i, j);
// // var p4 = labels.At<Point>(i, j);
//
// // }
// // }
//
// // labels.SaveImage(@$"F:\GS_TEST_cccc{contNum}.png");
//
//
//
//
// // //var un = labels.dis
//
// // Console.ReadLine();
// // //foreach (var contour in contours1)
// // //{
// // // //if (hierarchy[contNum].Parent < 0)
// // // //{
// // // // var boundingRect = Cv2.BoundingRect(contour);
//
// // // // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // // // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, color, 20 * cNum), -1,
// // // // LineTypes.Link8, maxLevel: -1);
// // // // //colorSeparatedMats.Add(c);
// // // // dst0.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// // // //}
//
// // // var boundingRect = Cv2.BoundingRect(contour);
//
// // // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // //Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, 128, 20 * contNum), -1,
// // // // LineTypes.Link8, maxLevel: -1);
// // // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(hierarchy[contNum].Parent < 0 ? 255 : 0, 128, 20 * contNum), -1,
// // // LineTypes.Link8, maxLevel: -1);
// // // //colorSeparatedMats.Add(c);
// // // dst0.SaveImage(@$"F:\GS_TEST_c{contNum}.png");
//
//
//
//
// // // //var mean = Cv2.Mean(c, mask);
// // // //var notBlackContour = Cv2.Mean(c, mask)[0] > 0;
//
// // // //var averageInsideColor =
//
//
// // // //var c1 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // //var dst0 = c1.EmptyClone();
// // // //Cv2.BitwiseAnd(c1, c1, dst0, c.GetRectSubPix(boundingRect.Size, new Point2f(boundingRect.Left + (boundingRect.Width / 2), boundingRect.Top + (boundingRect.Height / 2))));
//
// // // //var c1 = c.CvtColor(ColorConversionCodes.GRAY2BGR);
// // // //var m1 = c1.InRange(new Scalar(0), new Scalar(255));
// // // //Cv2.FloodFill(c1, m1, new Point(0, 0), new Scalar(0, color, 20 * cNum));
//
// // // //dst0.SaveImage(@$"F:\GS_TEST_cc{cNum}_{contNum}.png");
// // // contNum++;
// // //}
//
// // //___
//
// // //var colorSeparatedMats = new List<Mat>();
// // //var cNum = 0;
// // //foreach (var color in colors)
// // //{
//
//
// // // //var c = m.InRange(new Scalar(color), new Scalar(color));
//
// // // var c = m.Threshold(0, 255, ThresholdTypes.Binary & ThresholdTypes.Otsu);
//
// // // var closing = c.EmptyClone();
//
// // // //var contours0 = closing.FindContoursAsMat(RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// // // //Cv2.MorphologyEx(c, closing, MorphTypes.Close, contours0[0]);
// // // Cv2.MorphologyEx(c, closing, MorphTypes.Close, null);
//
// // // //var contours0 = closing.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// // // Point[][] contours1;
// // // HierarchyIndex[] hierarchy;
// // // //closing.FindContours(out contours1, , RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
// // // closing.FindContours(out contours1, out hierarchy, RetrievalModes.Tree, ContourApproximationModes.ApproxNone);
//
// // // var contNum = 0;
//
// // // var aaaaa = contours1.Count();
//
// // // var a01 = hierarchy[0].Previous;
// // // var a02 = hierarchy[0].Next;
// // // var a03 = hierarchy[1].Previous;
// // // var a04 = hierarchy[1].Next;
//
// // // var aaa = hierarchy.Where(q => q.Parent < 0).ToList();
//
// // // foreach (var contour in contours1)
// // // {
// // // //if (hierarchy[contNum].Parent < 0)
// // // //{
// // // // var boundingRect = Cv2.BoundingRect(contour);
//
// // // // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // // // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, color, 20 * cNum), -1,
// // // // LineTypes.Link8, maxLevel: -1);
// // // // //colorSeparatedMats.Add(c);
// // // // dst0.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// // // //}
//
// // // var boundingRect = Cv2.BoundingRect(contour);
//
// // // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, color, 20 * cNum), -1,
// // // LineTypes.Link8, maxLevel: -1);
// // // //colorSeparatedMats.Add(c);
// // // dst0.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
//
//
//
//
// // // //var mean = Cv2.Mean(c, mask);
// // // //var notBlackContour = Cv2.Mean(c, mask)[0] > 0;
//
// // // //var averageInsideColor =
//
//
// // // //var c1 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // // //var dst0 = c1.EmptyClone();
// // // //Cv2.BitwiseAnd(c1, c1, dst0, c.GetRectSubPix(boundingRect.Size, new Point2f(boundingRect.Left + (boundingRect.Width / 2), boundingRect.Top + (boundingRect.Height / 2))));
//
// // // //var c1 = c.CvtColor(ColorConversionCodes.GRAY2BGR);
// // // //var m1 = c1.InRange(new Scalar(0), new Scalar(255));
// // // //Cv2.FloodFill(c1, m1, new Point(0, 0), new Scalar(0, color, 20 * cNum));
//
// // // //dst0.SaveImage(@$"F:\GS_TEST_cc{cNum}_{contNum}.png");
// // // contNum++;
// // // }
//
// // // //colorSeparatedMats.Add(c);
// // // //c.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
//
// // // cNum++;
// // //}
//
// // //foreach (var cMat in colorSeparatedMats)
// // //{
// // // cNum++;
// // //}
// // var boundingRect = Cv2.BoundingRect(contour);
// // var dst0 = Mat.Zeros(m.Size(), MatType.CV_8UC3).ToMat();
// // //var dst0 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // Cv2.DrawContours(dst0, contours1, contNum, new Scalar(0, color, 20 * cNum), -1,
// // LineTypes.Link8, maxLevel: -1);
// // //colorSeparatedMats.Add(c);
// // dst0.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// // //var mean = Cv2.Mean(c, mask);
// // //var notBlackContour = Cv2.Mean(c, mask)[0] > 0;
// // //var averageInsideColor =
// // //var c1 = new Mat(boundingRect.Size, MatType.CV_8UC3, new Scalar(0, color, 20 * cNum));
// // //var dst0 = c1.EmptyClone();
// // //Cv2.BitwiseAnd(c1, c1, dst0, c.GetRectSubPix(boundingRect.Size, new Point2f(boundingRect.Left + (boundingRect.Width / 2), boundingRect.Top + (boundingRect.Height / 2))));
// // //var c1 = c.CvtColor(ColorConversionCodes.GRAY2BGR);
// // //var m1 = c1.InRange(new Scalar(0), new Scalar(255));
// // //Cv2.FloodFill(c1, m1, new Point(0, 0), new Scalar(0, color, 20 * cNum));
// // //dst0.SaveImage(@$"F:\GS_TEST_cc{cNum}_{contNum}.png");
// // contNum++;
// // }
// // //colorSeparatedMats.Add(c);
// // //c.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// // cNum++;
//
// // var contours = m.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// // var a = contours.Count();
// // //var c = contours.Where(q => q.).Count();
// // //var nbl = m.FindNonZero();
// // //var contours1 = nbl.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// // //var b = contours1.Count();
// // var biggestContourRect = Cv2.BoundingRect(contours[0]);
// // Mat dst = new Mat();
// // Cv2.Rectangle(dst,
// // new Point(biggestContourRect.X, biggestContourRect.Y),
// // new Point(biggestContourRect.X + biggestContourRect.Width, biggestContourRect.Y + biggestContourRect.Height),
// // new Scalar(255, 255, 255), 2);
// // }
// //foreach (var cMat in colorSeparatedMats)
// //{
// // cNum++;
// //}
// //c.SaveImage(@$"F:\GS_TEST_c{cNum}.png");
// var contours = m.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// var a = contours.Count();
// //var c = contours.Where(q => q.).Count();
// //var nbl = m.FindNonZero();
// //var contours1 = nbl.FindContoursAsArray(RetrievalModes.List, ContourApproximationModes.ApproxNone);
// //var b = contours1.Count();
// var biggestContourRect = Cv2.BoundingRect(contours[0]);
// Mat dst = new Mat();
// Cv2.Rectangle(dst,
// new Point(biggestContourRect.X, biggestContourRect.Y),
// new Point(biggestContourRect.X + biggestContourRect.Width, biggestContourRect.Y + biggestContourRect.Height),
// new Scalar(255, 255, 255), 2);
// }
// }
}
}

View File

@ -1,26 +1,30 @@
.:^. ::.
.:~77??: !??7!^:
:!7??????: !??????7~.
:7?????????: !?????????~.
.!???????????: !???????????^
.7????????????: !????????????~
.7?????????????: !?????????????~
!??????????????: !??????????????:
.???????????????: !??????????????!
^???????????????: !??????????????7
:???????????????~ .7??????????????7
.????????????????~. .:7???????????????!
~?????????????????77!7??????????????????.
7?????????????????????????????????????^
.7J??????????????????????????????????^
~?J?????????????????????????????J7:
.!?JJ???????????????????????JJ7^
.~7?JJJ???????????????JJJ?!:
.^!7???JJJJJJJJ????7~:.
..:^^~~~~~^^:.
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB
PPPP5YYJ?7!!~^^::::^^~~!77?JJYYYYYJJJ???777777?JY5PGGB###&&&##BB

View File

@ -0,0 +1,30 @@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@55@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@Y 5@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@J J@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@7 ?@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@#~ !&@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@B: ^B@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@B. :B@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@#: :&@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@J Y@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@J Y@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@&#####&@@@@@@@@@&^ ^&@@@@@@@@&&#####&@@@@@@@
@@@@BJ!:.....::~7YG&@@@@#^ ^#@@@@&GY7~:......:!Y#@@@@
@@#7 :?B@@@&~ !&@@@B?: 7#@@
@B: 7#@@@7 7@@@B! :#@
@! .J@@@7 7@@@J. 7@
@~ 7@@@~ !@@@7 ~@
@Y :7YPGBBBBG5?^ Y@@#. :#@@J ~?5GBBBBGPY7: Y@
@@~ ^P&@@@@@@@@@@@@B! .&@@J Y@@#. 7B@@@@@@@@@@@@&P^ !@@
@@&7 7@@@@@@@@@@@@@@@@@J 5@@B #@@Y Y@@@@@@@@@@@@@@@@&! 7&@@
@@@@5::&@@@@@@@@@@@@@@@&&B ?&&B..#&&? B&&@@@@@@@@@@@@@@@&.^P@@@@
@@@@@&B@@@@@@@@@@@@@@@@&&B.G&&B..#&&P.B&&@@@@@@@@@@@@@@@@B&@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@5^@@@# .#@@&:P@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@PJG@@@#:P@@@5 P@@@5^#@@@PYP@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@&~ G@5^5@@@#: :#@@@5^P@P !@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@&^ ^77#@@@@J Y@@@@B77: ~@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@&PY5G#@@@@@@#: ^&@@@@@@#G5YP&@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@G .B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@PG@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

View File

@ -0,0 +1,30 @@
7! JY Y&:::::#@#YJ?!?@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
.JJ^~5&^.:P@&&&&&@@B!7JYP@@@@&5YYYYYYYYYYY#@@@@@@@@@@@@@@@@@@@@@
B@@@@@@PJ5P5YYJJ?P@@@@@@@@@@@# P@@@@@BYYG@&5YP@@@@@@@
@@@@@@P. ?@@@@@@@@@@# P@@@@5 !: !@@@@@@
@@@@@5 ^B@@@@@@@@&!~~~~~~~~~~~B@@@@7 .&@@@@@
@@@@5 .Y@@@@@@@@@@@@@@@@@@@@@@@@@&?: .!B@@@@@@
@@@5 .#@@@@@@@@@@@@@@@@@@@@@@@@@@&G! :5#@@@@@@@@
@@@#7 :B@@@@@@@@@#B@@@@@@@@@@@@@@@@@@@G&@@@@@@@@@@
@@@@@5. :#@@@&YB@@@&^:&@@@BY&@@@@@@@@@@@@@#GGB#@@@@@@
@@@@@@#~ ^#@@@@@! !B@P 5@#7 ~@@@@@@@@@@@5!. ^?B@@@
@@@@@@@@YJJYY55PPP&@GG#&@&~ .P5 YP. ^&@&#GG@@@@#^ !PBBGJ. Y@@
@@@@@@@@@@@@@@@@@@@@G!..~JP! ~ ~ ~PJ~..!G@@@@! 5@@@@@@#: B@
@@@@@@@@@@@@@@@@@@@@@@#Y~. :. .: .~Y#@@@@@@~ P@@@@@@&: G@
@@@@@@@@@@@@@@@@@@#5J7!!!~: :~!!!7?5#@@G. ?G##BY^ ?@@
@@@@@@@@@@@@@@@@@@#5J?77!~: :~!77?J5#@@@#?: .~P@@@
@@@@@@@@@@@@@@@@@@@@@@#J~. :. .: .~JB@@@@@@@@@&BPYY5G#@@@@@
@@@@@@&#GGG#&@@@@@@@G!..~JP~ ~ ~ ~PJ~:.~G@@@&#B#@@@@@@@@@@@@@
@@@@P!: :7G@@@@@BG#&@&^ .P5 YP. ^&@&#GB@#7: .^5@@@@@@@@@@@
@@&! 7@@@@@@@@@! 7#@P 5@#7 ~@@@@@@! G@@@@@@@@@@
@@J Y@@@@@@@@5B@@@&^:&@@@#Y&@@@@@5 ^#@@@@@@@@@@
@@J J@@@@@@@@@@@@@@##@@@@@@@@@@@@@BY77?P&@@@@@@@@@@@
@@&~ ~&@@@@@@J^^^^^^^~~J@@@@@@#BB#@@@@@@@@@@@@@@@@@@@@
@@@@Y^. .~5@@@@@@&! !&@@@JYGGPYP@@@@@@@@@@@&BPPB&@
@@@@@@#G555G#@@@@@@@B^ ^#@@?P@@@@?5@@@@@#GJ!^..^75&@
@@@@@@@@@@@@@@@@@@@P .G@@5J5PG7~Y5J!^..^7YG&@@@@@
@@@@@@@@@@@@@@@@@@@B^ :B@@@GJ!!?! ^5#@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@&! !&@@GJ5B&@77##B5?^..:!YG&@@@@
@@@@@@@@@@@@@@@@@@@@@@? J@@@&~#@@@B7#@@@@@@&GY7^::~Y#@
@@@@@@@@@@@@@@@@@@@@@@@57777777!!P@@@@@GYY55P&@@@@@@@@@@@@&BB#@@
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@