C++程序  |  184行  |  5.66 KB

/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * 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.
 */

/* ---- includes ----------------------------------------------------------- */

#include "b_BasicEm/Functions.h"
#include "b_BasicEm/Int16Arr.h"
#include "b_BasicEm/Math.h"
#include "b_ImageEm/HistoEq16.h"
#include "b_ImageEm/UInt16ByteImage.h"

/* ---- typedefs ----------------------------------------------------------- */

/* ---- constants ---------------------------------------------------------- */

/* ------------------------------------------------------------------------- */

/* ========================================================================= */
/*                                                                           */
/* ---- \ghd{ auxiliary functions } ---------------------------------------- */
/*                                                                           */
/* ========================================================================= */

/** Computes grey level histogram of given image. */
void bim_createHisto16( uint16* histoPtrA, 
						const struct bim_UInt16ByteImage* imagePtrA )
{
	uint32 iL;
	uint16* dstPtrL;
	const uint16* srcPtrL;
	
	/* init histogram array with 0 */
	dstPtrL = histoPtrA;
	for( iL = 256; iL > 0; iL-- )
	{
		*dstPtrL++ = 0;
	}
	
	srcPtrL = imagePtrA->arrE.arrPtrE;
	dstPtrL = histoPtrA;
	/* calculate histogram (assuming even image width) */
	for( iL = imagePtrA->arrE.sizeE; iL > 0; iL-- ) 
	{
		dstPtrL[ ( *srcPtrL & 0x0FF ) ]++;	
		dstPtrL[ ( *srcPtrL >> 8 ) ]++;
		srcPtrL++;
	}
}

/* ------------------------------------------------------------------------- */

/** Computes grey level histogram of given image. */
void bim_createHistoOfSection16( uint16* histoPtrA,
								 const struct bts_Int16Rect* sectionPtrA, 
								 const struct bim_UInt16ByteImage* imagePtrA )
{
	uint32 xL, yL;
	const uint16* srcPtrL;
	uint16* dstPtrL;
	struct bts_Int16Rect sectionL = *sectionPtrA;
	uint32 sectWidthL;
	uint32 sectHeightL;
	int32 imgWidthL = imagePtrA->widthE;
	int32 imgHeightL = imagePtrA->heightE;

	bbs_ERROR0( "bim_createHistoOfSection16(...): not implemented" );

	/* adjustments */
	sectionL.x1E = bbs_max( 0, sectionL.x1E );
	sectionL.x1E = bbs_min( imgWidthL, sectionL.x1E );
	sectionL.x2E = bbs_max( 0, sectionL.x2E );
	sectionL.x2E = bbs_min( imgWidthL, sectionL.x2E );
	sectionL.y1E = bbs_max( 0, sectionL.y1E );
	sectionL.y1E = bbs_min( imgHeightL, sectionL.y1E );
	sectionL.y2E = bbs_max( 0, sectionL.y2E );
	sectionL.y2E = bbs_min( imgHeightL, sectionL.y2E );

	sectWidthL = sectionL.x2E - sectionL.x1E;
	sectHeightL = sectionL.y2E - sectionL.y1E;

	/* init histogram with 0 */
	dstPtrL = histoPtrA;
	for( xL = 256; xL > 0; xL-- )
	{
		*dstPtrL++ = 0;
	}
	
	/* calculate histogram */
	srcPtrL = imagePtrA->arrE.arrPtrE + sectionL.y1E * imgWidthL + sectionL.x1E;
	dstPtrL = histoPtrA;
	for( yL = 0; yL < sectHeightL; yL++ )
	{
		for( xL = 0; xL < sectWidthL; xL++ )
		{
			dstPtrL[ ( *srcPtrL & 0x0FF ) ]++;	
			dstPtrL[ ( *srcPtrL >> 8 ) ]++;
			srcPtrL++;
			/* dstPtrL[ *srcPtrL++ ]++;	 */
		}
		srcPtrL += imgWidthL - sectWidthL;
	}
}

/* ------------------------------------------------------------------------- */

/** equalize image using given histogram */
void bim_equalize16( struct bim_UInt16ByteImage* imagePtrA, 
					 const uint16* histoPtrA )
{
	uint32 kL;
	uint32 sumL = 0;
	uint32 totalSumL = 0;
	const uint16* histoArrPtrL;
	uint16* dstPtrL;
	uint16 mappingL[ 256 ];

	/* determine number of counts in histogram */
	histoArrPtrL = histoPtrA;
	for( kL = 256; kL > 0; kL-- )
	{
		totalSumL += *histoArrPtrL++;
	}

	if( totalSumL == 0 ) totalSumL = 1;
	
	/* compute transfer function (cumulative histogram) */
	histoArrPtrL = histoPtrA;
	for( kL = 0; kL < 256; kL++ )
	{
		sumL += *histoArrPtrL++;
		mappingL[ kL ] = ( sumL * 255 ) / totalSumL;
	}

	/* remap pixel values */
	dstPtrL = imagePtrA->arrE.arrPtrE;
	for( kL = imagePtrA->arrE.sizeE; kL > 0; kL-- )
	{
		*dstPtrL = mappingL[ *dstPtrL & 0x00FF ] | ( mappingL[ *dstPtrL >> 8 ] << 8 );
		dstPtrL++;
	}
}

/* ------------------------------------------------------------------------- */

/* ========================================================================= */
/*                                                                           */
/* ---- \ghd{ external functions } ----------------------------------------- */
/*                                                                           */
/* ========================================================================= */

/* ------------------------------------------------------------------------- */

void bim_UInt16ByteImage_equalize( struct bim_UInt16ByteImage* imagePtrA )
{
	uint16 histogramL[ 256 ];
	bim_createHisto16( histogramL, imagePtrA );
	bim_equalize16( imagePtrA, histogramL );
}

/* ------------------------------------------------------------------------- */

void bim_UInt16ByteImage_equalizeSection( struct bim_UInt16ByteImage* imagePtrA,
										  const struct bts_Int16Rect* sectionPtrA )
{
	uint16 histogramL[ 256 ];
	bim_createHistoOfSection16( histogramL, sectionPtrA, imagePtrA );
	bim_equalize16( imagePtrA, histogramL );
}

/* ========================================================================= */