public int getNumBinsAngle() { return transform.getHeight(); }
/** * Computes the derivative along the x and y axes */ public static void process(GrayF32 orig, GrayF32 derivX, GrayF32 derivY) { final float[] data = orig.data; final float[] imgX = derivX.data; final float[] imgY = derivY.data; final int width = orig.getWidth(); final int height = orig.getHeight() - 1; final int stride = orig.stride; for (int y = 1; y < height; y++) { int indexX = derivX.startIndex + derivX.stride * y + 1; int indexY = derivY.startIndex + derivY.stride * y + 1; int indexSrc = orig.startIndex + stride * y + 1; final int endX = indexSrc + width - 2; for (; indexSrc < endX; indexSrc++) { imgX[indexX++] = (data[indexSrc + 1] - data[indexSrc - 1]) * 0.5f; imgY[indexY++] = (data[indexSrc + stride] - data[indexSrc - stride]) * 0.5f; } } }
/** * Computes derivative of GrayF32. None of the images can be sub-images. */ public static void process_F32(GrayF32 orig, GrayF32 derivX, GrayF32 derivY) { final float[] data = orig.data; final float[] imgX = derivX.data; final float[] imgY = derivY.data; final int width = orig.getWidth(); final int height = orig.getHeight() - 1; for (int y = 1; y < height; y++) { int endX = width * y + width - 1; for (int index = width * y + 1; index < endX; index++) { float v = (data[index + width + 1] - data[index - width - 1]) * 0.25F; float w = (data[index + width - 1] - data[index - width + 1]) * 0.25F; imgY[index] = (data[index + width] - data[index - width]) * 0.5F + v + w; imgX[index] = (data[index + 1] - data[index - 1]) * 0.5F + v - w; } } } }
/** * Computes the derivative along the x and y axes */ public static void process(GrayF32 orig, GrayF32 derivX, GrayF32 derivY) { final float[] data = orig.data; final float[] imgX = derivX.data; final float[] imgY = derivY.data; final int width = orig.getWidth(); final int height = orig.getHeight() - 1; final int stride = orig.stride; for (int y = 0; y < height; y++) { int indexX = derivX.startIndex + derivX.stride * y; int indexY = derivY.startIndex + derivY.stride * y; int indexSrc = orig.startIndex + orig.stride * y; final int endX = indexSrc + width - 1; for (; indexSrc < endX; indexSrc++) { float val = data[indexSrc]; imgX[indexX++] = (data[indexSrc + 1] - val); imgY[indexY++] = (data[indexSrc + stride] - val); } } }
/** * Computes the derivative along the x and y axes */ public static void process(GrayF32 orig, GrayF32 derivX, GrayF32 derivY) { final float[] data = orig.data; final float[] imgX = derivX.data; final float[] imgY = derivY.data; final int width = orig.getWidth(); final int height = orig.getHeight(); final int stride = orig.stride; for (int y = 1; y < height; y++) { int indexX = derivX.startIndex + derivX.stride*y + 1; int indexY = derivY.startIndex + derivY.stride*y + 1; int indexSrc = orig.startIndex + orig.stride*y + 1; final int endX = indexSrc + width - 1; for (; indexSrc < endX; indexSrc++) { float val = data[indexSrc]; imgX[indexX++] = (val - data[indexSrc - 1]); imgY[indexY++] = (val - data[indexSrc - stride]); } } }
public static double computeError(GrayF32 imgA, GrayF32 imgB ) { final int h = imgA.getHeight(); final int w = imgA.getWidth(); double total = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { double difference = Math.abs(imgA.get(x,y)-imgB.get(x,y)); total += difference; } } return total / (w*h); }
/** * Converts ImageGray into Bitmap. * * @see #declareStorage(android.graphics.Bitmap, byte[]) * * @param input Input gray scale image. * @param output Output Bitmap image. * @param storage Byte array used for internal storage. If null it will be declared internally. */ public static void grayToBitmap( GrayF32 input , Bitmap output , byte[] storage ) { if( output.getWidth() != input.getWidth() || output.getHeight() != input.getHeight() ) { throw new IllegalArgumentException("Image shapes are not the same"); } if( storage == null ) storage = declareStorage(output,null); ImplConvertBitmap.grayToArray(input, storage,output.getConfig()); output.copyPixelsFromBuffer(ByteBuffer.wrap(storage)); }
/** * Converts ImageGray into Bitmap. * * @see #declareStorage(android.graphics.Bitmap, byte[]) * * @param input Input gray scale image. * @param output Output Bitmap image. * @param storage Byte array used for internal storage. If null it will be declared internally. */ public static void grayToBitmap( GrayF32 input , Bitmap output , byte[] storage ) { if( output.getWidth() != input.getWidth() || output.getHeight() != input.getHeight() ) { throw new IllegalArgumentException("Image shapes are not the same"); } if( storage == null ) storage = declareStorage(output,null); ImplConvertBitmap.grayToArray(input, storage,output.getConfig()); output.copyPixelsFromBuffer(ByteBuffer.wrap(storage)); }
/** * Converts Bitmap image into GrayF32. * * @see #declareStorage(android.graphics.Bitmap, byte[]) * * @param input Input Bitmap image. * @param output Output image. If null a new one will be declared. * @param storage Byte array used for internal storage. If null it will be declared internally. * @return The converted gray scale image. */ public static GrayF32 bitmapToGray( Bitmap input , GrayF32 output , byte[] storage) { if( output == null ) { output = new GrayF32( input.getWidth() , input.getHeight() ); } else if( output.getWidth() != input.getWidth() || output.getHeight() != input.getHeight() ) { throw new IllegalArgumentException("Image shapes are not the same"); } if( storage == null ) storage = declareStorage(input,null); input.copyPixelsToBuffer(ByteBuffer.wrap(storage)); ImplConvertBitmap.arrayToGray(storage, input.getConfig(), output); return output; }
public static double computeWeightedError(GrayF32 imgA, GrayF32 imgB , GrayF32 imgWeight ) { final int h = imgA.getHeight(); final int w = imgA.getWidth(); double total = 0; double totalWeight = 0; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { float weight = imgWeight.get(x,y); double difference = Math.abs(imgA.get(x,y)-imgB.get(x,y)); total += difference*weight; totalWeight += weight; } } return total / totalWeight; }
public static void horizontal3(Kernel1D_F32 kernel , GrayF32 input, GrayF32 output , int skip ) { final float[] dataSrc = input.data; final float[] dataDst = output.data; final float k1 = kernel.data[0]; final float k2 = kernel.data[1]; final float k3 = kernel.data[2]; final int radius = kernel.getRadius(); final int widthEnd = UtilDownConvolve.computeMaxSide(input.width,skip,radius); final int height = input.getHeight(); final int offsetX = UtilDownConvolve.computeOffset(skip,radius); for( int i = 0; i < height; i++ ) { int indexDst = output.startIndex + i*output.stride + offsetX/skip; int j = input.startIndex + i*input.stride - radius; final int jEnd = j+widthEnd; for( j += offsetX; j <= jEnd; j += skip ) { int indexSrc = j; float total = (dataSrc[indexSrc++] ) * k1; total += (dataSrc[indexSrc++])*k2; total += (dataSrc[indexSrc])*k3; dataDst[indexDst++] = total; } } }
public static void horizontal(Kernel1D_F32 kernel, ImageBorder_F32 input, GrayF32 output ) { final float[] dataDst = output.data; final float[] dataKer = kernel.data; final int offset = kernel.getOffset(); final int kernelWidth = kernel.getWidth(); final int width = output.getWidth(); final int height = output.getHeight(); final int borderRight = kernelWidth-offset-1; for (int y = 0; y < height; y++) { int indexDest = output.startIndex + y * output.stride; for ( int x = 0; x < offset; x++ ) { float total = 0; for (int k = 0; k < kernelWidth; k++) { total += input.get(x+k-offset,y) * dataKer[k]; } dataDst[indexDest++] = total; } indexDest = output.startIndex + y * output.stride + width-borderRight; for ( int x = width-borderRight; x < width; x++ ) { float total = 0; for (int k = 0; k < kernelWidth; k++) { total += input.get(x+k-offset,y) * dataKer[k]; } dataDst[indexDest++] = total; } } }
public static void vertical(Kernel1D_F32 kernel, ImageBorder_F32 input, GrayF32 output ) { final float[] dataDst = output.data; final float[] dataKer = kernel.data; final int offset = kernel.getOffset(); final int kernelWidth = kernel.getWidth(); final int width = output.getWidth(); final int height = output.getHeight(); final int borderBottom = kernelWidth-offset-1; for ( int x = 0; x < width; x++ ) { int indexDest = output.startIndex + x; for (int y = 0; y < offset; y++, indexDest += output.stride) { float total = 0; for (int k = 0; k < kernelWidth; k++) { total += input.get(x,y+k-offset) * dataKer[k]; } dataDst[indexDest] = total; } indexDest = output.startIndex + (height-borderBottom) * output.stride + x; for (int y = height-borderBottom; y < height; y++, indexDest += output.stride) { float total = 0; for (int k = 0; k < kernelWidth; k++ ) { total += input.get(x,y+k-offset) * dataKer[k]; } dataDst[indexDest] = total; } } }
/** * <p> * Computes the absolute value of the difference between each pixel in the two images.<br> * d(x,y) = |img1(x,y) - img2(x,y)| * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param diff Absolute value of difference image. Modified. */ public static void diffAbs(GrayF32 imgA , GrayF32 imgB , GrayF32 diff ) { InputSanityCheck.checkSameShape(imgA,imgB,diff); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexDiff = diff.getStartIndex() + y * diff.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexDiff++ ) { diff.data[indexDiff] = Math.abs((imgA.data[indexA] ) - (imgB.data[indexB] )); } } }
public static void horizontal(Kernel1D_F32 kernel, GrayF32 input, GrayF32 output ) { final int offset = kernel.getOffset(); final int width = input.getWidth(); final int height = input.getHeight(); for (int y = 0; y < height; y++) { for( int x = 0; x < width; x++ ) { float total = 0; float weight = 0; int startX = x - offset; int endX = startX+kernel.getWidth(); if( startX < 0 ) startX = 0; if( endX > width ) endX = width; for( int j = startX; j < endX; j++ ) { float v = kernel.get(j-x+offset); total += input.get(j,y)*v; weight += v; } output.set(x,y, total/weight ); } } }
public static void vertical(Kernel1D_F32 kernel, GrayF32 input, GrayF32 output ) { final int offset = kernel.getOffset(); final int width = input.getWidth(); final int height = input.getHeight(); for (int y = 0; y < height; y++) { for( int x = 0; x < width; x++ ) { float total = 0; float weight = 0; int startY = y - offset; int endY = startY + kernel.getWidth(); if( startY < 0 ) startY = 0; if( endY > height ) endY = height; for( int i = startY; i < endY; i++ ) { float v = kernel.get(i-y+offset); total += input.get(x,i)*v; weight += v; } output.set(x,y, total/weight ); } } }
/** * <p> * Performs pixel-wise subtraction.<br> * output(x,y) = imgA(x,y) - imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void subtract(GrayF32 imgA , GrayF32 imgB , GrayF32 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) - (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise addition<br> * output(x,y) = imgA(x,y) + imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void add(GrayF32 imgA , GrayF32 imgB , GrayF32 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) + (imgB.data[indexB] )); } } }
/** * <p> * Performs pixel-wise multiplication<br> * output(x,y) = imgA(x,y) * imgB(x,y) * </p> * @param imgA Input image. Not modified. * @param imgB Input image. Not modified. * @param output Output image. Modified. */ public static void multiply(GrayF32 imgA , GrayF32 imgB , GrayF32 output ) { InputSanityCheck.checkSameShape(imgA,imgB,output); final int h = imgA.getHeight(); final int w = imgA.getWidth(); for (int y = 0; y < h; y++) { int indexA = imgA.getStartIndex() + y * imgA.getStride(); int indexB = imgB.getStartIndex() + y * imgB.getStride(); int indexOut = output.getStartIndex() + y * output.getStride(); int indexEnd = indexA+w; // for(int x = 0; x < w; x++ ) { for (; indexA < indexEnd; indexA++, indexB++, indexOut++ ) { output.data[indexOut] = ((imgA.data[indexA] ) * (imgB.data[indexB] )); } } }
/** * Computes the derivative of 'orig' along the x and y axes */ public static void process( GrayF32 orig, GrayF32 derivX, GrayF32 derivY) { final int width = orig.getWidth(); final int height = orig.getHeight(); for (int y = 1; y < height - 1; y++) { for (int x = 1; x < width - 1; x++) { float dy = -(orig.get(x - 1, y - 1) * 0.25F + orig.get(x, y - 1) * 0.5F + orig.get(x + 1, y - 1) * 0.25F); dy += (orig.get(x - 1, y + 1) * 0.25F + orig.get(x, y + 1) * 0.5F + orig.get(x + 1, y + 1) * 0.25F); float dx = -(orig.get(x - 1, y - 1) * 0.25F + orig.get(x - 1, y) * 0.5F + orig.get(x - 1, y + 1) * 0.25F); dx += (orig.get(x + 1, y - 1) * 0.25F + orig.get(x + 1, y) * 0.5F + orig.get(x + 1, y + 1) * 0.25F); derivX.set(x, y, dx); derivY.set(x, y, dy); } } }