@@ -55,43 +55,45 @@ Ref<Binarizer> HybridBinarizer::createBinarizer(Ref<LuminanceSource> source) {
5555}
5656
5757int HybridBinarizer::initBlockIntegral () {
58- blockIntegral_ = new Array<int >(width * height);
58+ blockIntegralWidth = subWidth_ + 1 ;
59+ blockIntegralHeight = subHeight_ + 1 ;
60+ blockIntegral_ = new Array<int >(blockIntegralWidth * blockIntegralHeight);
5961
6062 int * integral = blockIntegral_->data ();
6163
6264 // unsigned char* therow = grayByte_->getByteRow(0);
6365
6466 // first row only
65- int rs = 0 ;
6667
67- for (int j = 0 ; j < width ; j++) {
68+ for (int j = 0 ; j < blockIntegralWidth ; j++) {
6869 integral[j] = 0 ;
6970 }
7071
71- for (int i = 0 ; i < height ; i++) {
72- integral[i * width ] = 0 ;
72+ for (int i = 0 ; i < blockIntegralHeight ; i++) {
73+ integral[i * blockIntegralWidth ] = 0 ;
7374 }
7475
75- for (int j = 0 ; j < subWidth_; j++) {
76- rs += blocks_[j].threshold ;
77- integral[width + j + 1 ] = rs;
78- }
79-
80- // remaining cells are sum above and to the left
81- int offset = width;
82- int offsetBlock = 0 ;
83-
84- for (int i = 1 ; i < subHeight_; ++i) {
85- // therow = grayByte_->getByteRow(i);
86- offsetBlock = i * subWidth_;
87-
88- rs = 0 ;
89-
90- offset += width;
91-
92- for (int j = 0 ; j < subWidth_; ++j) {
93- rs += blocks_[offsetBlock + j].threshold ;
94- integral[offset + j + 1 ] = rs + integral[offset - width + j + 1 ];
76+ // compute block integral
77+ // O - - - - - - -
78+ // | | |
79+ // | - - -A - B
80+ // | | |
81+ // | - - C - D
82+ // |
83+ // |
84+
85+ int D, D1, B, C, A;
86+ for (int row = 1 ; row < blockIntegralHeight; row++) {
87+ for (int col = 1 ; col < blockIntegralWidth; col++ ) {
88+
89+ D = row * blockIntegralWidth + col;
90+ B = (row - 1 ) * blockIntegralWidth + col;
91+ C = row * blockIntegralWidth + (col - 1 );
92+ A = (row - 1 ) * blockIntegralWidth + (col - 1 );
93+
94+ D1 = (row - 1 ) * subWidth_ + (col - 1 );
95+
96+ integral[D] = blocks_[D1].threshold + integral[B] + integral[C] - integral[A];
9597 }
9698 }
9799
@@ -201,13 +203,25 @@ void HybridBinarizer::calculateThresholdForBlock(Ref<ByteMatrix>& _luminances, i
201203 int sum = 0 ;
202204 // int sum2 = 0;
203205
204- int offset1 = (top - THRES_BLOCKSIZE) * (subWidth + 1 ) + left - THRES_BLOCKSIZE;
205- int offset2 = (top + THRES_BLOCKSIZE + 1 ) * (subWidth + 1 ) + left - THRES_BLOCKSIZE;
206-
207206 int blocksize = THRES_BLOCKSIZE * 2 + 1 ;
208207
209- sum = blockIntegral[offset1] - blockIntegral[offset1 + blocksize] -
210- blockIntegral[offset2] + blockIntegral[offset2 + blocksize];
208+ // calculate sum from Rect ABCD
209+ // O - - - - - - -
210+ // | | |
211+ // | - - -A - B
212+ // | | |
213+ // | - - C - D
214+ // |
215+ // |
216+ int bottom = top + blocksize;
217+ int right = left + blocksize;
218+
219+ // coordinate in blockIntegral are translated by (1, 1)
220+ int D = (bottom + 1 ) * blockIntegralWidth + (right + 1 );
221+ int C = (bottom + 1 ) * blockIntegralWidth + (left + 1 - 1 );
222+ int B = (top + 1 - 1 ) * blockIntegralWidth + (right + 1 );
223+ int A = (top + 1 - 1 ) * blockIntegralWidth + (left + 1 - 1 );
224+ sum = blockIntegral[D] - blockIntegral[B] - blockIntegral[C] + blockIntegral[A];
211225
212226 int average = sum / blockArea;
213227 thresholdBlock (_luminances, xoffset, yoffset, average, matrix, err_handler);
0 commit comments