You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

257 lines
12 KiB

using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using UTIL;
namespace Test_img
{
public partial class Form1 : Form
{
public struct FIFO_ITEM
{
public UInt16 x;
public UInt16 y;
}
unsafe public struct THE_POINT
{
public FIFO_ITEM* pi;
public Byte* pm;
}
public struct CLUSTER_COORD
{
public UInt16 count; // number of points (pixels) in cluster
public Byte excluded; // flag, cluster should be ignored if TRUE
public Byte marker; // cluster identicator
public ARM_RECT rect; // rectangular area of cluster (in pixels)
}
public struct ARM_RECT
{
public UInt16 left;
public UInt16 top;
public UInt16 right;
public UInt16 bottom;
}
const UInt16 CELL_SIZE = 8; // cluster cell size, in pix
const Byte __FALSE = 0;
const Byte __TRUE = 1;
const Byte NO_MARKER = 0; // 'no marker' cluster identifier
//static UInt16 IMAGE_CELL_CX = (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE);
//static UInt16 IMAGE_CELL_CY = (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE);
static UInt16 IMAGE_CELL_CX = 0; // (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE);
static UInt16 IMAGE_CELL_CY = 0; // (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE);
List<FIFO_ITEM> v = new List<FIFO_ITEM>();
List<PointF> FIFO_ITEM_f = new List<PointF>();
static UInt16 IMAGE_CX = 0;
static UInt16 IMAGE_CY = 0;
static FIFO_ITEM[] g_shot_array = new FIFO_ITEM[4096]; // shot XY-coordinates from FIFO1
static UInt16 g_shot_count; // number of shot XY-coordinate pairs in FIFO1
static UInt16 g_cluster_count; // number of clusters (8x8) in FIFO1
static UInt16 g_super_cluster_count; // number of super clusters in FIFO1
static CLUSTER_COORD[] g_cluster_coords = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // clusters mass centre & coordinates in FIFO1
static CLUSTER_COORD[] g_cluster_ptrs = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; //
static CLUSTER_COORD[] g_super_cluster_coords = null; // new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY];
StreamWriter logsw = null;
private void SearchClusters(UInt16 porog)
{
InitClusters();
GetPix(porog);
BuildClustersArray();
EnlargeClustersInArray();
}
private void InitClusters()
{
IMAGE_CX = (UInt16)(bm.Width - 1);
IMAGE_CY = (UInt16)(bm.Height - 1);
IMAGE_CELL_CX = (UInt16)((IMAGE_CX + CELL_SIZE - 1) / CELL_SIZE);
IMAGE_CELL_CY = (UInt16)((IMAGE_CY + CELL_SIZE - 1) / CELL_SIZE);
g_cluster_coords = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; // clusters mass centre & coordinates in FIFO1
g_cluster_ptrs = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY]; //
g_super_cluster_coords = new CLUSTER_COORD[IMAGE_CELL_CX * IMAGE_CELL_CY];
String logfilename = "log_" + DateTime.Now.ToString("yyyyMMdd_HHmmss") + ".log";
//logsw = new StreamWriter(logfilename, false);
//logsw.WriteLine($"IMAGE_CX {IMAGE_CX}");
//logsw.WriteLine($"IMAGE_CY {IMAGE_CY}");
//logsw.WriteLine($"IMAGE_CELL_CX {IMAGE_CELL_CX}");
//logsw.WriteLine($"IMAGE_CELL_CY {IMAGE_CELL_CY}");
//logsw.WriteLine($"g_cluster_coords {IMAGE_CELL_CX * IMAGE_CELL_CY}");
//logsw.WriteLine($"g_cluster_ptrs {IMAGE_CELL_CX * IMAGE_CELL_CY}");
//logsw.WriteLine($"g_super_cluster_coords {IMAGE_CELL_CX * IMAGE_CELL_CY}");
//logsw.WriteLine();
}
private void GetPix(UInt16 porog)
{
UnsafeBitmap btm = new UnsafeBitmap(bm);
btm.LockBitmap();
g_shot_count = 0;
for (int y = 0; y < bm.Height; y++)
{
for (int x = 0; x < bm.Width; x++)
{
PixelData c = btm.GetPixel(x, y);
if (c.blue >= porog)
{
FIFO_ITEM t = new FIFO_ITEM();
t.x = (UInt16)x;
t.y = (UInt16)y;
//logsw.WriteLine($"Shoot n={g_shot_count} x={x} y={y}");
g_shot_array[g_shot_count++] = t;
v.Add(t);
}
}
}
btm.UnlockBitmap();
btm.Dispose();
//logsw.WriteLine();
}
private void BuildClustersArray()
{
Byte marker;
UInt16 i, j, k, count;
UInt16 l, t, r, b;
for (i = 0; i < g_shot_count; i++)
{
FIFO_ITEM fi = g_shot_array[i];
UInt16 x = (UInt16)(fi.x / CELL_SIZE);
UInt16 y = (UInt16)(fi.y / CELL_SIZE);
g_cluster_coords[y * IMAGE_CELL_CX + x].count++;
g_cluster_coords[y * IMAGE_CELL_CX + x].excluded = __FALSE;
g_cluster_coords[y * IMAGE_CELL_CX + x].marker = NO_MARKER;
g_cluster_coords[y * IMAGE_CELL_CX + x].rect.left = (UInt16)(x * CELL_SIZE);
g_cluster_coords[y * IMAGE_CELL_CX + x].rect.top = (UInt16)(y * CELL_SIZE);
g_cluster_coords[y * IMAGE_CELL_CX + x].rect.right = (UInt16)((x + 1) * CELL_SIZE);
g_cluster_coords[y * IMAGE_CELL_CX + x].rect.bottom = (UInt16)((y + 1) * CELL_SIZE);
//logsw.WriteLine($"Cl_1 i={i} n={y * IMAGE_CELL_CX + x} " +
// $"count={g_cluster_coords[y * IMAGE_CELL_CX + x].count - 1} " +
// $"excluded={g_cluster_coords[y * IMAGE_CELL_CX + x].excluded} " +
// $"marker={g_cluster_coords[y * IMAGE_CELL_CX + x].marker} " +
// $"left={(UInt16)(x * CELL_SIZE)} " +
// $"top={(UInt16)(y * CELL_SIZE)} " +
// $"right={(UInt16)((x + 1) * CELL_SIZE)} " +
// $"bottom={(UInt16)((y + 1) * CELL_SIZE)}");
}
//logsw.WriteLine();
g_cluster_count = 0;
for (i = 0; i < IMAGE_CELL_CX * IMAGE_CELL_CY; i++)
{
if (g_cluster_coords[i].count > 0)
{
//logsw.WriteLine($"Cl_2 i={i} g_cluster_count{g_cluster_count} x={g_cluster_coords[i].rect.left} y={g_cluster_coords[i].rect.top}");
g_cluster_ptrs[g_cluster_count++] = g_cluster_coords[i];
}
}
//logsw.WriteLine();
marker = NO_MARKER;
for (i = 0; i < g_cluster_count; i++)
{
Int16 x1 = (Int16)((g_cluster_ptrs[i].rect.left + g_cluster_ptrs[i].rect.right) / 2);
Int16 y1 = (Int16)((g_cluster_ptrs[i].rect.top + g_cluster_ptrs[i].rect.bottom) / 2);
if (g_cluster_ptrs[i].marker == NO_MARKER)
g_cluster_ptrs[i].marker = (++marker);
for (j = (UInt16)(i + 1); j < g_cluster_count; j++)
{
Int16 x2 = (Int16)((g_cluster_ptrs[j].rect.left + g_cluster_ptrs[j].rect.right) / 2);
Int16 y2 = (Int16)((g_cluster_ptrs[j].rect.top + g_cluster_ptrs[j].rect.bottom) / 2);
if (Math.Abs(x1 - x2) <= CELL_SIZE && Math.Abs(y1 - y2) <= CELL_SIZE)
{
if (g_cluster_ptrs[j].marker == NO_MARKER)
{
g_cluster_ptrs[j].marker = g_cluster_ptrs[i].marker;
}
else
{
for (k = 0; k < g_cluster_count; k++)
{
if (g_cluster_ptrs[k].marker == g_cluster_ptrs[j].marker)
{
g_cluster_ptrs[k].marker = g_cluster_ptrs[i].marker;
//logsw.WriteLine($"Cl_3 i={i} j={j} k={k} x={g_cluster_ptrs[k].rect.left} y={g_cluster_ptrs[k].rect.top} m={g_cluster_ptrs[k].marker}");
}
}
}
}
}
}
//logsw.WriteLine();
g_super_cluster_count = 0;
for (i = 1; i <= marker; i++)
{
count = 0;
l = 0x7fff;
t = 0x7fff;
r = 0;
b = 0;
for (j = 0; j < g_cluster_count; j++)
{
if (g_cluster_ptrs[j].marker == i)
{
if (g_cluster_ptrs[j].rect.left < l) l = g_cluster_ptrs[j].rect.left;
if (g_cluster_ptrs[j].rect.top < t) t = g_cluster_ptrs[j].rect.top;
if (g_cluster_ptrs[j].rect.right > r) r = g_cluster_ptrs[j].rect.right;
if (g_cluster_ptrs[j].rect.bottom > b) b = g_cluster_ptrs[j].rect.bottom;
count += g_cluster_ptrs[j].count;
}
}
if (count > 0)
{
g_super_cluster_coords[g_super_cluster_count].count = count;
g_super_cluster_coords[g_super_cluster_count].excluded = __FALSE;
g_super_cluster_coords[g_super_cluster_count].marker = NO_MARKER;
g_super_cluster_coords[g_super_cluster_count].rect.left = l;
g_super_cluster_coords[g_super_cluster_count].rect.top = t;
g_super_cluster_coords[g_super_cluster_count].rect.right = r;
g_super_cluster_coords[g_super_cluster_count].rect.bottom = b;
g_super_cluster_count++;
}
}
//for (int m = 0; m < g_super_cluster_count; m++)
//{
// logsw.WriteLine($"Cl_5 m={m} " +
// $"count={g_super_cluster_coords[m].count} " +
// $"excluded={g_super_cluster_coords[m].excluded} " +
// $"marker={g_super_cluster_coords[m].marker} " +
// $"left={g_super_cluster_coords[m].rect.left} " +
// $"top={g_super_cluster_coords[m].rect.top} " +
// $"right={g_super_cluster_coords[m].rect.right} " +
// $"bottom={g_super_cluster_coords[m].rect.bottom}");
//}
//logsw.Close();
}
private void EnlargeClustersInArray()
{
UInt16 i;
for (i = 0; i < g_super_cluster_count; i++)
{
if (g_super_cluster_coords[i].rect.left >= CELL_SIZE) g_super_cluster_coords[i].rect.left -= CELL_SIZE;
if (g_super_cluster_coords[i].rect.top >= CELL_SIZE) g_super_cluster_coords[i].rect.top -= CELL_SIZE;
if (g_super_cluster_coords[i].rect.right <= IMAGE_CX - CELL_SIZE) g_super_cluster_coords[i].rect.right += CELL_SIZE;
if (g_super_cluster_coords[i].rect.bottom <= IMAGE_CY - CELL_SIZE) g_super_cluster_coords[i].rect.bottom += CELL_SIZE;
}
}
private Rectangle CLUSTER_COORD2Rect(CLUSTER_COORD c)
{
return new Rectangle(c.rect.left, c.rect.top, c.rect.right - c.rect.left, c.rect.bottom - c.rect.top);
}
}
}