📄 hist_eq.asm
字号:
/*******************************************************************************
Copyright(c) 2000 - 2002 Analog Devices. All Rights Reserved.
Developed by Joint Development Software Application Team, IPDC, Bangalore, India
for Blackfin DSPs ( Micro Signal Architecture 1.0 specification).
By using this module you agree to the terms of the Analog Devices License
Agreement for DSP Software.
********************************************************************************
Module Name : hist_eq.asm
Label Name : __hist_eq
Version : 1.3
Change History :
Version Date Author Comments
1.3 11/18/2002 Swarnalatha Tested with VDSP++ 3.0
compiler 6.2.2 on
ADSP-21535 Rev.0.2
1.2 11/13/2002 Swarnalatha Tested with VDSP++ 3.0
on ADSP-21535 Rev. 0.2
1.1 02/28/2002 Srinivas Modified to match
silicon cycle count
1.0 05/16/2001 Srinivas Original
Description : This routine implements the histogram equalization of a given
gray level vector. Input is expected in 8 bit unsigned char
format.
Loop1 performs histogram calculation of the input vector.
Histogram will have same no of bins as input levels (ex. a 256
gray level image will have 256 bins to start with). In Loop2
Transformation Function (map) is obtained. Idea here is to
obtain a mapping vector which tries to make histogram, uniform
for a given number of bins, nBins.
Two thresholds, Incr = 255/(nBins-1) & Thresh = n/nBins are
calculated.
Algorithm for loop2 can be written as-
NewThresh = Thresh;
MapValue = 0;
CumHist = 0;
for(i=0;i<255;i++)
{
map[i] = MapValue;
CumHist += Histogram[i];
if(NewThresh > CumHist)
{
NewThresh += Thresh;
MapValue += Incr;
if(MapValue > 255)
MapValue = 255;
}
}
Mapping of the input to new levels is done in Loop3.
i.e.
PtrOutput[i] = map[PtrInput[i]];
Assumptions : (1) The total number of pixels, n is assumed to be even.
Prototype : void hist_eq(char* PtrInput, char* PtrOutput, int n,
short nBins)
PtrInput :- Pointer to input vector.
PtrOutput :- Pointer to output vector.
n :- size of the input vector
nBins :- number of bins.
Registers Used : R0-R7, I0, I1, M0, M1, L0, L1, P0-P5, LC0, LC1.
Performance :
Code size : 272 Bytes
Cycle count : 2645 Cycles (for n = 26, and nBins=5).
*******************************************************************************/
.section L1_code;
.align 8;
.global __hist_eq;
__hist_eq:
P1 = R0; //Pointer to Input buffer
P2 = R1; //Pointer to output buffer
[--SP] = (R7:4,P5:3); //Store register values in stack
[--SP] = RETS; //Store RETS register value in stack
L0 = 0;
L1 = 0;
P4 = R2; //n
R0 = R2 << 0 || R1 = [SP+44];
//n
//Load the no of bins
CALL __udiv16; //Thresh = n/(nBins)
R6 = R0; //Thresh
R1 += -1; //nBins-1
R0 = 255; //MaxValue
CALL __udiv16; //Incr = (MaxValue)/(nBins-1)
P5 = 255; //(MaxValue)
P3 = P1; //PtrInput
P0 = -1024; //Offset for 256 element buffer
R1 = R2 - R2 (NS) || R3 =[SP ++ P0];
//Load 0 for initialization, Add offset to stack
//pointer
I1 = SP; //Pointer to histogram buffer
/* Loop for initialization of histogram buffer to zero */
[I1++] = R1;
LSETUP(LSTEND0,LSTEND0) LC0 = P5;
//(MaxValue)
LSTEND0:
[I1++] = R1; //Initialization of histogram buffer to zero
/* Loop for histogram calculation */
R2 = SP;
R2 = R2 >> 2 || R1 = B[P3++] (Z);
//Load pixel value
R1 = (R1 + R2) << 2; //Starting address of hist buffer + offset
I1 = R1;
R3 = 1; //For incrementing histogram counter
R4 = R6; //NewThreshold
R1 = B[P3++] (Z);
LSETUP(LSTART1,LEND1) LC1 = P4 >> 1;
//(n/2)
LSTART1:R1 = (R1 + R2) << 2;//Starting address of hist buffer + offset
I0 = R1;
R7 = [I1]; //Load counter value, Load pixel value
R7 = R7 + R3; //Increment the count value
[I1] = R7 || R1 = B[P3++] (Z);
//Repeat the loop
R1 = (R1 + R2) << 2;
I1 = R1;
R7 = [I0];
R7.L = R7.L + R3.L (NS);
LEND1: [I0] = R7 || R1 = B[P3++] (Z);
I1 = SP; //I1 pointing to the start of histogram buffer
R2 = 0; //Cum hist value
R3 = R1-R1(ns) || R7 = [I1];
//Load hist value
R5 = P5;
/* Loop for obtaining Transformation Function (map) */
LSETUP(LSTART2,LEND2) LC1 = P5;
//(MaxValue)
LSTART2:R7 = R7 + R2 (ns) || [I1++] = R3; //Cumulative histogram value
//Store the map value
CC = R7 <= R4; //Check if it Cum hist is less than NewThreshold
R1 = R4 + R6; //NewThreshold = NewThreshold + Thresh
R2 = R3 + R0; //MapValue = MapValue + Incr
R2 = MIN(R2,R5); //Saturate if MapValue exceeds MaxValue
IF !CC R4 = R1; //NewThreshold
IF !CC R3 = R2; //MapValue
LEND2: R2 = R7 << 0 || R7 = [I1];
//Update Cumulative histogram value, Load next hist
// value
/* Loop for mapping of input pixel values */
R3 = B[P1++] (Z)|| [I1] = R3;
//Load first pixel value, Store the last map value
R4 = R3 << 2 || R7 = B[P1++] (Z);
//Offset, Load next pixel
M1 = R4; //Offset
I1 = SP; //Starting address of map buffer
R1 = R7 << 2 || R3 = B[P1++] (Z);
M0 = R1;
I1 += M1;
R4 = R3 << 2 || R5 = [I1];
M1 = R4;
LSETUP(LSTART3,LEND3) LC1 = P4 >> 1;
//(n/2)
LSTART3:I0 = SP; //Starting address of map buffer
R7 = B[P1++] (Z)|| R2 = [I0++M0];
//Load pixel value, Add offset to I0
R1 = R7 << 2 || R2 = [I0] || B[P2++] = R5;
//Offset, Mapped value, Store mapped value
I1 = SP; //Repeat the iteration
M0 = R1; //Offset
R3 = B[P1++] (Z)|| R5 = [I1++M1];
//Load pixel value, Add offset to I1
R4 = R3 << 2 || R5 = [I1] || B[P2++] = R2; //Offset, Mapped value
//Store the mapped output
LEND3: M1 = R4;
TERMINATE: SP -= P0; //Releasing the memory
RETS=[SP++]; //Pop the RETS register value from stack
(R7:4,P5:3) = [SP++]; //Pop the register values from stack
RTS;
NOP; //to avoid one stall if LINK or UNLINK happens to be
//the next instruction after RTS in the memory.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -