use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.
the class ImplEnhanceHistogram method equalizeLocalInner.
/**
* Performs local histogram equalization just on the inner portion of the image
*/
public static void equalizeLocalInner(GrayU16 input, int radius, int histogramLength, GrayU16 output, GrowArray<DogArray_I32> workspaces) {
// CONCURRENT_REMOVE_LINE
final DogArray_I32 work = workspaces.grow();
int width = 2 * radius + 1;
int area = width * width;
int maxValue = histogramLength - 1;
// CONCURRENT_BELOW BoofConcurrency.loopBlocks(radius,input.height-radius,workspaces,(work,y0,y1)->{
int y0 = radius, y1 = input.height - radius;
int[] histogram = BoofMiscOps.checkDeclare(work, histogramLength, false);
for (int y = y0; y < y1; y++) {
localHistogram(input, 0, y - radius, width, y + radius + 1, histogram);
// compute equalized pixel value using the local histogram
int inputValue = input.unsafe_get(radius, y);
int sum = 0;
for (int i = 0; i <= inputValue; i++) {
sum += histogram[i];
}
output.set(radius, y, (sum * maxValue) / area);
// start of old and new columns in histogram region
int indexOld = input.startIndex + y * input.stride;
int indexNew = indexOld + width;
// index of pixel being examined
int indexIn = input.startIndex + y * input.stride + radius + 1;
int indexOut = output.startIndex + y * output.stride + radius + 1;
for (int x = radius + 1; x < input.width - radius; x++) {
// update local histogram by removing the left column
for (int i = -radius; i <= radius; i++) {
histogram[input.data[indexOld + i * input.stride] & 0xFFFF]--;
}
// update local histogram by adding the right column
for (int i = -radius; i <= radius; i++) {
histogram[input.data[indexNew + i * input.stride] & 0xFFFF]++;
}
// compute equalized pixel value using the local histogram
inputValue = input.data[indexIn++] & 0xFFFF;
sum = 0;
for (int i = 0; i <= inputValue; i++) {
sum += histogram[i];
}
output.data[indexOut++] = (short) ((sum * maxValue) / area);
indexOld++;
indexNew++;
}
}
// CONCURRENT_ABOVE }});
}
use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.
the class BinaryThinning method apply.
/**
* Applies the thinning algorithm. Runs for the specified number of loops or until no change is detected.
*
* @param binary Input binary image which is to be thinned. This is modified
* @param maxLoops Maximum number of thinning loops. Set to -1 to run until the image is no longer modified.
*/
public void apply(GrayU8 binary, int maxLoops) {
this.binary = binary;
inputBorder.setImage(binary);
ones0.reset();
zerosOut.reset();
findOnePixels(ones0);
for (int loop = 0; (loop < maxLoops || maxLoops == -1) && ones0.size > 0; loop++) {
boolean changed = false;
// do one cycle through all the masks
for (int i = 0; i < masks.length; i++) {
zerosOut.reset();
ones1.reset();
masks[i].apply(ones0, ones1, zerosOut);
changed |= ones0.size != ones1.size;
// mark all the pixels that need to be set to 0 as 0
for (int j = 0; j < zerosOut.size(); j++) {
binary.data[zerosOut.get(j)] = 0;
}
// swap the lists
DogArray_I32 tmp = ones0;
ones0 = ones1;
ones1 = tmp;
}
if (!changed)
break;
}
}
use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.
the class ImplMedianHistogramInner method process.
/**
* Applies a median image filter.
*
* @param input Input image. Not modified.
* @param output Filtered output image. Modified.
* @param radiusX Size of the filter region. x-axis
* @param radiusY Size of the filter region. Y-axis
* @param work Creates local work space arrays
*/
public static void process(GrayU8 input, GrayU8 output, int radiusX, int radiusY, GrowArray<DogArray_I32> work) {
int w = 2 * radiusX + 1;
int h = 2 * radiusY + 1;
// CONCURRENT_REMOVE_BELOW
DogArray_I32 array = work.grow();
// sanity check to make sure the image isn't too small to be processed by this algorithm
if (input.width < w || input.height < h)
return;
// defines what the median is. technically this is an approximation because if even it's the ave
// of the two elements in the middle. I'm not aware of libraries which actually do this.
int threshold = (w * h) / 2 + 1;
// CONCURRENT_BELOW BoofConcurrency.loopBlocks(radiusY, output.height-radiusY, h, work, (array,y0,y1)->{
final int y0 = radiusY, y1 = input.height - radiusY;
int[] histogram = BoofMiscOps.checkDeclare(array, 256, false);
for (int y = y0; y < y1; y++) {
int seed = input.startIndex + (y - radiusY) * input.stride;
Arrays.fill(histogram, 0);
// compute the median value for the first x component and initialize the system
for (int yi = 0; yi < h; yi++) {
int idx = seed + yi * input.stride;
int end = idx + w;
while (idx < end) {
histogram[(input.data[idx++] & 0xFF)]++;
}
}
// Compute the median value
int count = 0, median = 0;
while (true) {
count += histogram[median];
if (count >= threshold)
break;
median++;
}
output.data[output.startIndex + y * output.stride + radiusX] = (byte) median;
// remove the left most pixel from the histogram
count += removeSide(input.data, input.stride, h, histogram, seed, median);
for (int x = radiusX + 1; x < input.width - radiusX; x++) {
seed = input.startIndex + (y - radiusY) * input.stride + (x - radiusX);
// add the right most pixels to the histogram
count += addSide(input.data, input.stride, h, histogram, seed + w - 1, median);
// find the median, using the previous solution as a starting point
if (count >= threshold) {
while (count >= threshold) {
count -= histogram[median--];
}
median += 1;
count += histogram[median];
} else {
while (count < threshold) {
median += 1;
count += histogram[median];
}
}
output.data[output.startIndex + y * output.stride + x] = (byte) median;
// remove the left most pixels from the histogram
count += removeSide(input.data, input.stride, h, histogram, seed, median);
}
}
// CONCURRENT_ABOVE }});
}
use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.
the class ConvolveImageUnrolled_SB_U8_I8_Div method convolve11.
public static void convolve11(Kernel2D_S32 kernel, GrayU8 src, GrayI8 dest, int divisor, @Nullable GrowArray<DogArray_I32> workspaces) {
workspaces = BoofMiscOps.checkDeclare(workspaces, DogArray_I32::new);
// CONCURRENT_REMOVE_LINE
final DogArray_I32 work = workspaces.grow();
final byte[] dataSrc = src.data;
final byte[] dataDst = dest.data;
final int width = src.getWidth();
final int height = src.getHeight();
final int halfDivisor = divisor / 2;
final int kernelRadius = kernel.getRadius();
final int kernelWidth = 2 * kernelRadius + 1;
// CONCURRENT_BELOW BoofConcurrency.loopBlocks(kernelRadius, height-kernelRadius, kernelWidth, workspaces, (work, y0, y1)->{
final int y0 = kernelRadius, y1 = height - kernelRadius;
int[] totalRow = BoofMiscOps.checkDeclare(work, src.width, false);
for (int y = y0; y < y1; y++) {
// first time through the value needs to be set
int k1 = kernel.data[0];
int k2 = kernel.data[1];
int k3 = kernel.data[2];
int k4 = kernel.data[3];
int k5 = kernel.data[4];
int k6 = kernel.data[5];
int k7 = kernel.data[6];
int k8 = kernel.data[7];
int k9 = kernel.data[8];
int k10 = kernel.data[9];
int k11 = kernel.data[10];
int indexSrcRow = src.startIndex + (y - kernelRadius) * src.stride - kernelRadius;
for (int x = kernelRadius; x < width - kernelRadius; x++) {
int indexSrc = indexSrcRow + x;
int total = 0;
total += (dataSrc[indexSrc++] & 0xFF) * k1;
total += (dataSrc[indexSrc++] & 0xFF) * k2;
total += (dataSrc[indexSrc++] & 0xFF) * k3;
total += (dataSrc[indexSrc++] & 0xFF) * k4;
total += (dataSrc[indexSrc++] & 0xFF) * k5;
total += (dataSrc[indexSrc++] & 0xFF) * k6;
total += (dataSrc[indexSrc++] & 0xFF) * k7;
total += (dataSrc[indexSrc++] & 0xFF) * k8;
total += (dataSrc[indexSrc++] & 0xFF) * k9;
total += (dataSrc[indexSrc++] & 0xFF) * k10;
total += (dataSrc[indexSrc] & 0xFF) * k11;
totalRow[x] = total;
}
// rest of the convolution rows are an addition
for (int i = 1; i < 11; i++) {
indexSrcRow = src.startIndex + (y + i - kernelRadius) * src.stride - kernelRadius;
k1 = kernel.data[i * 11 + 0];
k2 = kernel.data[i * 11 + 1];
k3 = kernel.data[i * 11 + 2];
k4 = kernel.data[i * 11 + 3];
k5 = kernel.data[i * 11 + 4];
k6 = kernel.data[i * 11 + 5];
k7 = kernel.data[i * 11 + 6];
k8 = kernel.data[i * 11 + 7];
k9 = kernel.data[i * 11 + 8];
k10 = kernel.data[i * 11 + 9];
k11 = kernel.data[i * 11 + 10];
for (int x = kernelRadius; x < width - kernelRadius; x++) {
int indexSrc = indexSrcRow + x;
int total = 0;
total += (dataSrc[indexSrc++] & 0xFF) * k1;
total += (dataSrc[indexSrc++] & 0xFF) * k2;
total += (dataSrc[indexSrc++] & 0xFF) * k3;
total += (dataSrc[indexSrc++] & 0xFF) * k4;
total += (dataSrc[indexSrc++] & 0xFF) * k5;
total += (dataSrc[indexSrc++] & 0xFF) * k6;
total += (dataSrc[indexSrc++] & 0xFF) * k7;
total += (dataSrc[indexSrc++] & 0xFF) * k8;
total += (dataSrc[indexSrc++] & 0xFF) * k9;
total += (dataSrc[indexSrc++] & 0xFF) * k10;
total += (dataSrc[indexSrc] & 0xFF) * k11;
totalRow[x] += total;
}
}
int indexDst = dest.startIndex + y * dest.stride + kernelRadius;
for (int x = kernelRadius; x < width - kernelRadius; x++) {
dataDst[indexDst++] = (byte) ((totalRow[x] + halfDivisor) / divisor);
}
}
// CONCURRENT_INLINE });
}
use of org.ddogleg.struct.DogArray_I32 in project BoofCV by lessthanoptimal.
the class ImplConvolveBox method vertical.
public static void vertical(GrayU16 input, GrayI16 output, int radius, @Nullable GrowArray<DogArray_I32> workspaces) {
workspaces = BoofMiscOps.checkDeclare(workspaces, DogArray_I32::new);
// CONCURRENT_REMOVE_LINE
final DogArray_I32 work = workspaces.grow();
final int kernelWidth = radius * 2 + 1;
final int backStep = kernelWidth * input.stride;
// CONCURRENT_BELOW BoofConcurrency.loopBlocks(radius, output.height-radius, kernelWidth, workspaces, (work, y0,y1)->{
final int y0 = radius, y1 = output.height - radius;
int[] totals = BoofMiscOps.checkDeclare(work, input.width, false);
for (int x = 0; x < input.width; x++) {
int indexIn = input.startIndex + (y0 - radius) * input.stride + x;
int indexOut = output.startIndex + output.stride * y0 + x;
int total = 0;
int indexEnd = indexIn + input.stride * kernelWidth;
for (; indexIn < indexEnd; indexIn += input.stride) {
total += input.data[indexIn] & 0xFFFF;
}
totals[x] = total;
output.data[indexOut] = (short) total;
}
// change the order it is processed in to reduce cache misses
for (int y = y0 + 1; y < y1; y++) {
int indexIn = input.startIndex + (y + radius) * input.stride;
int indexOut = output.startIndex + y * output.stride;
for (int x = 0; x < input.width; x++, indexIn++, indexOut++) {
int total = totals[x] - (input.data[indexIn - backStep] & 0xFFFF);
totals[x] = total += input.data[indexIn] & 0xFFFF;
output.data[indexOut] = (short) total;
}
}
// CONCURRENT_INLINE });
}
Aggregations