@@ -55,43 +55,43 @@ 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+ int D, D1, B, C, A;
85+ for (int row = 1 ; row < blockIntegralHeight; row++) {
86+ for (int col = 1 ; col < blockIntegralWidth; col++ ) {
87+ D = row * blockIntegralWidth + col;
88+ B = (row - 1 ) * blockIntegralWidth + col;
89+ C = row * blockIntegralWidth + (col - 1 );
90+ A = (row - 1 ) * blockIntegralWidth + (col - 1 );
91+
92+ D1 = (row - 1 ) * subWidth_ + (col - 1 );
93+
94+ integral[D] = blocks_[D1].threshold + integral[B] + integral[C] - integral[A];
9595 }
9696 }
9797
@@ -201,13 +201,25 @@ void HybridBinarizer::calculateThresholdForBlock(Ref<ByteMatrix>& _luminances, i
201201 int sum = 0 ;
202202 // int sum2 = 0;
203203
204- int offset1 = (top - THRES_BLOCKSIZE) * (subWidth + 1 ) + left - THRES_BLOCKSIZE;
205- int offset2 = (top + THRES_BLOCKSIZE + 1 ) * (subWidth + 1 ) + left - THRES_BLOCKSIZE;
206-
207204 int blocksize = THRES_BLOCKSIZE * 2 + 1 ;
208205
209- sum = blockIntegral[offset1] - blockIntegral[offset1 + blocksize] -
210- blockIntegral[offset2] + blockIntegral[offset2 + blocksize];
206+ // calculate sum from Rect ABCD
207+ // O - - - - - - -
208+ // | | |
209+ // | - - -A - B
210+ // | | |
211+ // | - - C - D
212+ // |
213+ // |
214+ int bottom = top + blocksize;
215+ int right = left + blocksize;
216+
217+ // coordinate in blockIntegral are translated by (1, 1)
218+ int D = (bottom + 1 ) * blockIntegralWidth + (right + 1 );
219+ int C = (bottom + 1 ) * blockIntegralWidth + (left + 1 - 1 );
220+ int B = (top + 1 - 1 ) * blockIntegralWidth + (right + 1 );
221+ int A = (top + 1 - 1 ) * blockIntegralWidth + (left + 1 - 1 );
222+ sum = blockIntegral[D] - blockIntegral[B] - blockIntegral[C] + blockIntegral[A];
211223
212224 int average = sum / blockArea;
213225 thresholdBlock (_luminances, xoffset, yoffset, average, matrix, err_handler);
0 commit comments