All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.enhance.impl.ImplEnhanceHistogram_MT Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.6
Show newest version
/*
 * Copyright (c) 2011-2019, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.enhance.impl;

import boofcv.concurrency.BoofConcurrency;
import boofcv.concurrency.IWorkArrays;
import boofcv.struct.image.*;

import javax.annotation.Generated;

/**
 * 

* Functions for enhancing images using the image histogram. *

* *

* DO NOT MODIFY. This code was automatically generated by GenerateImplEnhanceHistogram. *

* * @author Peter Abeles */ @Generated("boofcv.alg.enhance.impl.GenerateImplEnhanceHistogram") public class ImplEnhanceHistogram_MT { public static void applyTransform( GrayU8 input , int transform[] , GrayU8 output ) { BoofConcurrency.loopFor(0,input.height,i->{ int indexInput = input.startIndex + i*input.stride; int indexOutput = output.startIndex + i*output.stride; for( int j = 0; j < input.width; j++ ) { output.data[indexOutput++] = (byte)transform[input.data[indexInput++] & 0xFF]; } }); } public static void applyTransform( GrayU16 input , int transform[] , GrayU16 output ) { BoofConcurrency.loopFor(0,input.height,i->{ int indexInput = input.startIndex + i*input.stride; int indexOutput = output.startIndex + i*output.stride; for( int j = 0; j < input.width; j++ ) { output.data[indexOutput++] = (short)transform[input.data[indexInput++] & 0xFFFF]; } }); } public static void applyTransform( GrayS8 input , int transform[] , int minValue , GrayS8 output ) { BoofConcurrency.loopFor(0,input.height,i->{ int indexInput = input.startIndex + i*input.stride; int indexOutput = output.startIndex + i*output.stride; for( int j = 0; j < input.width; j++ ) { output.data[indexOutput++] = (byte)transform[input.data[indexInput++]- minValue]; } }); } public static void applyTransform( GrayS16 input , int transform[] , int minValue , GrayS16 output ) { BoofConcurrency.loopFor(0,input.height,i->{ int indexInput = input.startIndex + i*input.stride; int indexOutput = output.startIndex + i*output.stride; for( int j = 0; j < input.width; j++ ) { output.data[indexOutput++] = (short)transform[input.data[indexInput++]- minValue]; } }); } public static void applyTransform( GrayS32 input , int transform[] , int minValue , GrayS32 output ) { BoofConcurrency.loopFor(0,input.height,i->{ int indexInput = input.startIndex + i*input.stride; int indexOutput = output.startIndex + i*output.stride; for( int j = 0; j < input.width; j++ ) { output.data[indexOutput++] = transform[input.data[indexInput++]- minValue]; } }); } /** * Inefficiently computes the local histogram, but can handle every possible case for image size and * local region size */ public static void equalizeLocalNaive( GrayU8 input , int radius , GrayU8 output , IWorkArrays workArrays ) { int width = 2*radius+1; int maxValue = workArrays.length()-1; BoofConcurrency.loopBlocks(0,input.height,(idx0,idx1)->{ int[] histogram = workArrays.pop(); for( int y = idx0; y < idx1; y++ ) { // make sure it's inside the image bounds int y0 = y-radius; int y1 = y+radius+1; if( y0 < 0 ) { y0 = 0; y1 = width; if( y1 > input.height ) y1 = input.height; } else if( y1 > input.height ) { y1 = input.height; y0 = y1 - width; if( y0 < 0 ) y0 = 0; } // pixel indexes int indexIn = input.startIndex + y*input.stride; int indexOut = output.startIndex + y*output.stride; for( int x = 0; x < input.width; x++ ) { // make sure it's inside the image bounds int x0 = x-radius; int x1 = x+radius+1; if( x0 < 0 ) { x0 = 0; x1 = width; if( x1 > input.width ) x1 = input.width; } else if( x1 > input.width ) { x1 = input.width; x0 = x1 - width; if( x0 < 0 ) x0 = 0; } // compute the local histogram localHistogram(input,x0,y0,x1,y1,histogram); // only need to compute up to the value of the input pixel int inputValue = input.data[indexIn++] & 0xFF; int sum = 0; for( int i = 0; i <= inputValue; i++ ) { sum += histogram[i]; } int area = (y1-y0)*(x1-x0); output.data[indexOut++] = (byte)((sum*maxValue)/area); } } }); } /** * Performs local histogram equalization just on the inner portion of the image */ public static void equalizeLocalInner( GrayU8 input , int radius , GrayU8 output , IWorkArrays workArrays ) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; BoofConcurrency.loopBlocks(radius,input.height-radius,(y0,y1)->{ int[] histogram = workArrays.pop(); 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] & 0xFF]--; } // update local histogram by adding the right column for( int i = -radius; i <= radius; i++ ) { histogram[input.data[indexNew + i*input.stride] & 0xFF]++; } // compute equalized pixel value using the local histogram inputValue = input.data[indexIn++] & 0xFF; sum = 0; for( int i = 0; i <= inputValue; i++ ) { sum += histogram[i]; } output.data[indexOut++] = (byte)((sum*maxValue)/area); indexOld++; indexNew++; } } }); } /** * Local equalization along a row. Image must be at least the histogram's width (2*r+1) in width and height. */ public static void equalizeLocalRow( GrayU8 input , int radius , int startY , GrayU8 output , IWorkArrays workArrays ) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; int[] histogram = workArrays.pop(); int[] transform = workArrays.pop(); // specify the top and bottom of the histogram window and make sure it is inside bounds int hist0 = startY; int hist1 = startY+width; if( hist1 > input.height ) { hist1 = input.height; hist0 = hist1 - width; } // the upper and lower bounds of the region being equalized int region0 = startY; int region1 = startY+radius; // local histogram and transformation localHistogram(input,0,hist0,width,hist1,histogram); int sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // equalize the first square region for( int y = region0; y < region1; y++ ) { int indexIn = input.startIndex + y*input.stride; int indexOut = output.startIndex + y*output.stride; for( int x = 0; x <= radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (byte)((transform[ inputValue ]*maxValue)/area); } } // move right while equalizing the columns one at a time for( int x = radius+1; x < input.width-radius-1; x++ ) { // remove the left most column int indexIn = input.startIndex + x-radius-1; for( int y = hist0; y < hist1; y++ ) { histogram[input.data[indexIn + y*input.stride] & 0xFF]--; } // add the right most column indexIn += width; for( int y = hist0; y < hist1; y++ ) { histogram[input.data[indexIn + y*input.stride] & 0xFF]++; } // compute transformation table sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output down the column indexIn = input.startIndex + region0*input.stride + x; int indexOut = output.startIndex + region0*output.stride + x; for( int y = 0; y < radius; y++ ) { int inputValue = input.data[indexIn] & 0xff; output.data[indexOut] = (byte)((transform[ inputValue ]*maxValue)/area); indexIn += input.stride; indexOut += output.stride; } } // equalize the final square region localHistogram(input,input.width-width,hist0,input.width,hist1,histogram); sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } for( int y = region0; y < region1; y++ ) { int x = input.width-radius-1; int indexIn = input.startIndex + y*input.stride + x; int indexOut = output.startIndex + y*output.stride + x; for( ; x < input.width; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (byte)((transform[ inputValue ]*maxValue)/area); } } workArrays.recycle(histogram); workArrays.recycle(transform); } /** * Local equalization along a column. Image must be at least the histogram's width (2*r+1) in width and height. */ public static void equalizeLocalCol( GrayU8 input , int radius , int startX , GrayU8 output , IWorkArrays workArrays) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; int[] histogram = workArrays.pop(); int[] transform = workArrays.pop(); // specify the top and bottom of the histogram window and make sure it is inside bounds int hist0 = startX; int hist1 = startX+width; if( hist1 > input.width ) { hist1 = input.width; hist0 = hist1 - width; } // initialize the histogram. ignore top border localHistogram(input,hist0,0,hist1,width,histogram); // compute transformation table int sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output across the row int indexIn = input.startIndex + radius*input.stride + startX; int indexOut = output.startIndex + radius*output.stride + startX; for( int x = 0; x < radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (byte)((transform[ inputValue ]*maxValue)/area); } // move down while equalizing the rows one at a time for( int y = radius+1; y < input.height-radius; y++ ) { // remove the top most row indexIn = input.startIndex + (y-radius-1)*input.stride; for( int x = hist0; x < hist1; x++ ) { histogram[input.data[indexIn + x] & 0xFF]--; } // add the bottom most row indexIn += width*input.stride; for( int x = hist0; x < hist1; x++ ) { histogram[input.data[indexIn + x] & 0xFF]++; } // compute transformation table sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output across the row indexIn = input.startIndex + y*input.stride + startX; indexOut = output.startIndex + y*output.stride + startX; for( int x = 0; x < radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (byte)((transform[ inputValue ]*maxValue)/area); } } workArrays.recycle(histogram); workArrays.recycle(transform); } /** * Computes the local histogram just for the specified inner region */ public static void localHistogram( GrayU8 input , int x0 , int y0 , int x1, int y1 , int histogram[] ) { for( int i = 0; i < histogram.length; i++ ) histogram[i] = 0; for( int i = y0; i < y1; i++ ) { int index = input.startIndex + i*input.stride + x0; int end = index + x1-x0; for( ; index < end; index++ ) { histogram[input.data[index] & 0xFF]++; } } } /** * Inefficiently computes the local histogram, but can handle every possible case for image size and * local region size */ public static void equalizeLocalNaive( GrayU16 input , int radius , GrayU16 output , IWorkArrays workArrays ) { int width = 2*radius+1; int maxValue = workArrays.length()-1; BoofConcurrency.loopBlocks(0,input.height,(idx0,idx1)->{ int[] histogram = workArrays.pop(); for( int y = idx0; y < idx1; y++ ) { // make sure it's inside the image bounds int y0 = y-radius; int y1 = y+radius+1; if( y0 < 0 ) { y0 = 0; y1 = width; if( y1 > input.height ) y1 = input.height; } else if( y1 > input.height ) { y1 = input.height; y0 = y1 - width; if( y0 < 0 ) y0 = 0; } // pixel indexes int indexIn = input.startIndex + y*input.stride; int indexOut = output.startIndex + y*output.stride; for( int x = 0; x < input.width; x++ ) { // make sure it's inside the image bounds int x0 = x-radius; int x1 = x+radius+1; if( x0 < 0 ) { x0 = 0; x1 = width; if( x1 > input.width ) x1 = input.width; } else if( x1 > input.width ) { x1 = input.width; x0 = x1 - width; if( x0 < 0 ) x0 = 0; } // compute the local histogram localHistogram(input,x0,y0,x1,y1,histogram); // only need to compute up to the value of the input pixel int inputValue = input.data[indexIn++] & 0xFFFF; int sum = 0; for( int i = 0; i <= inputValue; i++ ) { sum += histogram[i]; } int area = (y1-y0)*(x1-x0); output.data[indexOut++] = (short)((sum*maxValue)/area); } } }); } /** * Performs local histogram equalization just on the inner portion of the image */ public static void equalizeLocalInner( GrayU16 input , int radius , GrayU16 output , IWorkArrays workArrays ) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; BoofConcurrency.loopBlocks(radius,input.height-radius,(y0,y1)->{ int[] histogram = workArrays.pop(); 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++; } } }); } /** * Local equalization along a row. Image must be at least the histogram's width (2*r+1) in width and height. */ public static void equalizeLocalRow( GrayU16 input , int radius , int startY , GrayU16 output , IWorkArrays workArrays ) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; int[] histogram = workArrays.pop(); int[] transform = workArrays.pop(); // specify the top and bottom of the histogram window and make sure it is inside bounds int hist0 = startY; int hist1 = startY+width; if( hist1 > input.height ) { hist1 = input.height; hist0 = hist1 - width; } // the upper and lower bounds of the region being equalized int region0 = startY; int region1 = startY+radius; // local histogram and transformation localHistogram(input,0,hist0,width,hist1,histogram); int sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // equalize the first square region for( int y = region0; y < region1; y++ ) { int indexIn = input.startIndex + y*input.stride; int indexOut = output.startIndex + y*output.stride; for( int x = 0; x <= radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (short)((transform[ inputValue ]*maxValue)/area); } } // move right while equalizing the columns one at a time for( int x = radius+1; x < input.width-radius-1; x++ ) { // remove the left most column int indexIn = input.startIndex + x-radius-1; for( int y = hist0; y < hist1; y++ ) { histogram[input.data[indexIn + y*input.stride] & 0xFFFF]--; } // add the right most column indexIn += width; for( int y = hist0; y < hist1; y++ ) { histogram[input.data[indexIn + y*input.stride] & 0xFFFF]++; } // compute transformation table sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output down the column indexIn = input.startIndex + region0*input.stride + x; int indexOut = output.startIndex + region0*output.stride + x; for( int y = 0; y < radius; y++ ) { int inputValue = input.data[indexIn] & 0xff; output.data[indexOut] = (short)((transform[ inputValue ]*maxValue)/area); indexIn += input.stride; indexOut += output.stride; } } // equalize the final square region localHistogram(input,input.width-width,hist0,input.width,hist1,histogram); sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } for( int y = region0; y < region1; y++ ) { int x = input.width-radius-1; int indexIn = input.startIndex + y*input.stride + x; int indexOut = output.startIndex + y*output.stride + x; for( ; x < input.width; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (short)((transform[ inputValue ]*maxValue)/area); } } workArrays.recycle(histogram); workArrays.recycle(transform); } /** * Local equalization along a column. Image must be at least the histogram's width (2*r+1) in width and height. */ public static void equalizeLocalCol( GrayU16 input , int radius , int startX , GrayU16 output , IWorkArrays workArrays) { int width = 2*radius+1; int area = width*width; int maxValue = workArrays.length()-1; int[] histogram = workArrays.pop(); int[] transform = workArrays.pop(); // specify the top and bottom of the histogram window and make sure it is inside bounds int hist0 = startX; int hist1 = startX+width; if( hist1 > input.width ) { hist1 = input.width; hist0 = hist1 - width; } // initialize the histogram. ignore top border localHistogram(input,hist0,0,hist1,width,histogram); // compute transformation table int sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output across the row int indexIn = input.startIndex + radius*input.stride + startX; int indexOut = output.startIndex + radius*output.stride + startX; for( int x = 0; x < radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (short)((transform[ inputValue ]*maxValue)/area); } // move down while equalizing the rows one at a time for( int y = radius+1; y < input.height-radius; y++ ) { // remove the top most row indexIn = input.startIndex + (y-radius-1)*input.stride; for( int x = hist0; x < hist1; x++ ) { histogram[input.data[indexIn + x] & 0xFFFF]--; } // add the bottom most row indexIn += width*input.stride; for( int x = hist0; x < hist1; x++ ) { histogram[input.data[indexIn + x] & 0xFFFF]++; } // compute transformation table sum = 0; for( int i = 0; i < histogram.length; i++ ) { transform[i] = sum += histogram[i]; } // compute the output across the row indexIn = input.startIndex + y*input.stride + startX; indexOut = output.startIndex + y*output.stride + startX; for( int x = 0; x < radius; x++ ) { int inputValue = input.data[indexIn++] & 0xff; output.data[indexOut++] = (short)((transform[ inputValue ]*maxValue)/area); } } workArrays.recycle(histogram); workArrays.recycle(transform); } /** * Computes the local histogram just for the specified inner region */ public static void localHistogram( GrayU16 input , int x0 , int y0 , int x1, int y1 , int histogram[] ) { for( int i = 0; i < histogram.length; i++ ) histogram[i] = 0; for( int i = y0; i < y1; i++ ) { int index = input.startIndex + i*input.stride + x0; int end = index + x1-x0; for( ; index < end; index++ ) { histogram[input.data[index] & 0xFFFF]++; } } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy