using System;
using System.Collections.Generic;
using System.Text;
namespace LineSegmentSplitter
{
class HitAndMissTransformation
{
public static bool[,] AndTrue2D(bool[,] srcBoolMatrix, bool[,] kernel)
{
// kernel information
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
int halfHk = (hk - 1) / 2;
int halfWk = (wk - 1) / 2;
// matrix info
int height = srcBoolMatrix.GetLength(1);
int width = srcBoolMatrix.GetLength(0);
bool[,] expandSrcBoolMatrix = BoundFillingBackgroundIntensityExpand(srcBoolMatrix, kernel);
// prepare dst bool matrix
int expandHeight = expandSrcBoolMatrix.GetLength(1);
int expandWidth = expandSrcBoolMatrix.GetLength(0);
bool[,] expandDstBoolMatrix = new bool[expandWidth, expandHeight];
int xStart = halfWk;
int xEnd = width + halfWk;
int yStart = halfHk;
int yEnd = height + halfHk;
for (int x = xStart; x < xEnd; x++)
{
for (int y = yStart; y < yEnd; y++)
{
bool isHit = true;
// inside kernel
for (int kx = -1 * halfWk; kx <= halfWk; kx++)
{
for (int ky = -1 * halfHk; ky <= halfHk; ky++)
{
// kernel, expandSrcBoolMatrix, and expandDstBoolMatrix are bool[,]
if (kernel[kx + halfWk, ky + halfHk])
// kernel element is true
{
if (!expandSrcBoolMatrix[x + kx, y + ky])
// image element is false
{
isHit = false;
break;
}
}
}
}
expandDstBoolMatrix[x, y] = isHit;
}
}
bool[,] dstBoolMatrix = BoundFillingBackgroundIntensityShrink(expandDstBoolMatrix, kernel);
return dstBoolMatrix;
} // AndTrue2D()
public static bool[,] AndTrueFalse2D(bool[,] srcBoolMatrix, bool[,] kernel)
{
// kernel information
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
int halfHk = (hk - 1) / 2;
int halfWk = (wk - 1) / 2;
// matrix info
int height = srcBoolMatrix.GetLength(1);
int width = srcBoolMatrix.GetLength(0);
bool[,] expandSrcBoolMatrix = BoundFillingBackgroundIntensityExpand(srcBoolMatrix, kernel);
// prepare dst bool matrix
int expandHeight = expandSrcBoolMatrix.GetLength(1);
int expandWidth = expandSrcBoolMatrix.GetLength(0);
bool[,] expandDstBoolMatrix = new bool[expandWidth, expandHeight];
int xStart = halfWk;
int xEnd = width + halfWk;
int yStart = halfHk;
int yEnd = height + halfHk;
for (int x = xStart; x < xEnd; x++)
{
for (int y = yStart; y < yEnd; y++)
{
bool isHit = true;
// inside kernel
for (int kx = -1 * halfWk; kx <= halfWk; kx++)
{
for (int ky = -1 * halfHk; ky <= halfHk; ky++)
{
// kernel is a bool[,]
// expandSrcBoolMatrix, and expandDstBoolMatrix are bool[,]
if ((kernel[kx + halfWk, ky + halfHk] && !expandSrcBoolMatrix[x + kx, y + ky])
|| (!kernel[kx + halfWk, ky + halfHk] && expandSrcBoolMatrix[x + kx, y + ky]))
{
isHit = false;
break;
}
}
}
expandDstBoolMatrix[x, y] = isHit;
}
}
bool[,] dstBoolMatrix = BoundFillingBackgroundIntensityShrink(expandDstBoolMatrix, kernel);
return dstBoolMatrix;
} // AndTrueFalse2D()
public static bool[,] AndTrueFalseDontCare2D(bool[,] srcBoolMatrix, double[,] kernel)
{
// kernel information
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
int halfHk = (hk - 1) / 2;
int halfWk = (wk - 1) / 2;
// matrix info
int height = srcBoolMatrix.GetLength(1);
int width = srcBoolMatrix.GetLength(0);
bool[,] expandSrcBoolMatrix = BoundFillingBackgroundIntensityExpand(srcBoolMatrix, kernel);
// prepare dst bool matrix
int expandHeight = expandSrcBoolMatrix.GetLength(1);
int expandWidth = expandSrcBoolMatrix.GetLength(0);
bool[,] expandDstBoolMatrix = new bool[expandWidth, expandHeight];
int xStart = halfWk;
int xEnd = width + halfWk;
int yStart = halfHk;
int yEnd = height + halfHk;
for (int x = xStart; x < xEnd; x++)
{
for (int y = yStart; y < yEnd; y++)
{
bool isHit = true;
// inside kernel
for (int kx = -1 * halfWk; kx <= halfWk; kx++)
{
for (int ky = -1 * halfHk; ky <= halfHk; ky++)
{
// kernel is a double[,]
// expandSrcBoolMatrix, and expandDstBoolMatrix are bool[,]
if ((kernel[kx + halfWk, ky + halfHk] == 1 && !expandSrcBoolMatrix[x + kx, y + ky])
|| (kernel[kx + halfWk, ky + halfHk] == 0 && expandSrcBoolMatrix[x + kx, y + ky]))
{
isHit = false;
break;
}
}
}
expandDstBoolMatrix[x, y] = isHit;
}
}
bool[,] dstBoolMatrix = BoundFillingBackgroundIntensityShrink(expandDstBoolMatrix, kernel);
return dstBoolMatrix;
} // AndTrueFalseDontCare2D()
public static bool[,] BoundFillingBackgroundIntensityExpand(bool[,] srcBoolMatrix, int hk, int wk)
{
int height = srcBoolMatrix.GetLength(1);
int width = srcBoolMatrix.GetLength(0);
// half kernal width and height
int halfWk = (wk - 1) / 2;
int halfHk = (hk - 1) / 2;
// expanded matrix height & width
int heightA2 = height + 2 * halfHk;
int widthA2 = width + 2 * halfWk;
bool[,] expand = new bool[widthA2, heightA2];
int Wm1aHWK = width - 1 + halfWk;
int HHKm1 = halfHk - 1;
// upper row
for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++)
for (int ye = 0, y = halfHk; ye <= HHKm1; ye++, y--)
expand[xe, ye] = false;
// bottom row
int Hm1a2HHk = height - 1 + 2 * halfHk;
for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++)
for (int ye = height + halfHk, y = height - 2; ye <= Hm1a2HHk; ye++, y--)
expand[xe, ye] = false;
// left column
int HWKm1 = halfWk - 1;
int Hm1aHHK = height - 1 + halfHk;
for (int xe = 0, x = halfWk; xe <= HWKm1; xe++, x--)
for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++)
expand[xe, ye] = false;
// right column
int Wm1a2HWK = width - 1 + 2 * halfWk;
for (int xe = width + halfWk, x = width - 2; xe <= Wm1a2HWK; xe++, x--)
for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++)
expand[xe, ye] = false;
// center
for (int xe = halfWk, x = 0; xe <= Wm1aHWK; xe++, x++)
for (int ye = halfHk, y = 0; ye <= Hm1aHHK; ye++, y++)
expand[xe, ye] = srcBoolMatrix[x, y];
// left-top corner
for (int xc = 0, xe = 2 * halfWk; xc <= HWKm1; xc++, xe--)
for (int y = 0; y <= HHKm1; y++)
expand[xc, y] = false;
// right-top corner
for (int xc = width + halfWk, xe = width + halfWk - 2; xc <= Wm1a2HWK; xc++, xe--)
for (int y = 0; y <= HHKm1; y++)
expand[xc, y] = false;
// left-bottom corner
for (int xc = 0, xe = 2 * halfWk; xc <= HWKm1; xc++, xe--)
for (int y = height + halfHk; y <= Hm1a2HHk; y++)
expand[xc, y] = false;
// right-bottom corner
for (int xc = width + halfWk, xe = width + halfWk - 2; xc <= Wm1a2HWK; xc++, xe--)
for (int y = height + halfHk; y <= Hm1a2HHk; y++)
expand[xc, y] = false;
return expand;
}
public static bool[,] BoundFillingBackgroundIntensityExpand(bool[,] srcBoolMatrix, bool[,] kernel)
{
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
return BoundFillingBackgroundIntensityExpand(srcBoolMatrix, hk, wk);
} // BoundFillingBackgroundIntensityExpand()
public static bool[,] BoundFillingBackgroundIntensityExpand(bool[,] srcBoolMatrix, double[,] kernel)
{
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
return BoundFillingBackgroundIntensityExpand(srcBoolMatrix, hk, wk);
} // BoundFillingBackgroundIntensityExpand()
public static bool[,] BoundFillingBackgroundIntensityShrink(bool[,] expandSrcBoolMatrix, int hk, int wk)
{
// kernel information
int halfHk = (hk - 1) / 2;
int halfWk = (wk - 1) / 2;
// matrix info
int height = expandSrcBoolMatrix.GetLength(1);
int width = expandSrcBoolMatrix.GetLength(0);
// shink matrix info
int heightM2 = height - 2 * halfHk;
int widthM2 = width - 2 * halfWk;
bool[,] shrink = new bool[widthM2, heightM2];
int WmHWKm1 = width - halfWk - 1;
int HmHHKm1 = height - halfHk - 1;
// copy centre part
for (int xs = 0, x = halfWk; x <= WmHWKm1; x++, xs++)
for (int ys = 0, y = halfHk; y <= HmHHKm1; y++, ys++)
shrink[xs, ys] = expandSrcBoolMatrix[x, y];
return shrink;
}
public static bool[,] BoundFillingBackgroundIntensityShrink(bool[,] expandSrcBoolMatrix, bool[,] kernel)
{
// kernel information
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
return BoundFillingBackgroundIntensityShrink(expandSrcBoolMatrix, hk, wk);
} // BoundFillingBackgroundIntensityShrink()
public static bool[,] BoundFillingBackgroundIntensityShrink(bool[,] expandSrcBoolMatrix, double[,] kernel)
{
// kernel information
int hk = kernel.GetLength(1);
int wk = kernel.GetLength(0);
return BoundFillingBackgroundIntensityShrink(expandSrcBoolMatrix, hk, wk);
} // BoundFillingBackgroundIntensityShrink()
}
}