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
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); |
|
} |
|
} |
|
}
|
|
|