Skip to content

Commit 1a7d6f3

Browse files
committed
0.20200319: add blur args
1 parent 3d4c4e2 commit 1a7d6f3

File tree

3 files changed

+60
-49
lines changed

3 files changed

+60
-49
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Build:
1414

1515
Usage:
1616

17+
./aithreshold in.png out.png [T=0.15] [part=8] [blur=0]
18+
19+
Example:
20+
1721
./aithreshold images/image.png images/output.png
1822

1923
image.png

man/man1/aithreshold.1

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
.TH "AIThreshold" 1 "19 Mar 2020" 0.20200319 " User Manual"
2+
3+
.SH NAME
4+
aithreshold
5+
6+
.SH SYNOPSIS
7+
aithreshold <image_in> <image_out> [T=0.15] [part=8] [blur=0]
8+
9+
.SH DESCRIPTION
10+
Adaptive Thresholding Using the Integral Image
11+
12+
.SH EXAMPLE
13+
aithreshold image.png output.png 0.1 16 1
14+
15+
.SH COPYRIGHT
16+
Copyright 2017-2020 zvezdochiot.
17+
All rights reserved.
18+
19+
.SH SEE ALSO
20+
convert(1),
21+
imgtxtenh(1),
22+
imthreshold(1)
23+
24+
.SH CONTACTS
25+
Homepage: https://github.com/zvezdochiot/aithreshold
26+
Email: zvezdochiot@users.sourceforge.net

src/aithreshold.cpp

Lines changed: 30 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55

66
using namespace std;
77

8-
98
void thresholdIntegral(cv::Mat &inputMat, cv::Mat &outputMat, float T, int part)
109
{
10+
int nRows, nCols, S, s2, i, j;
11+
int x1, y1, x2, y2, count, sum, ip, it;
12+
cv::Mat sumMat;
13+
int *p_y1, *p_y2;
14+
uchar *p_inputMat, *p_outputMat;
15+
1116
// accept only char type matrices
1217
CV_Assert(!inputMat.empty());
1318
CV_Assert(inputMat.depth() == CV_8U);
@@ -17,91 +22,64 @@ void thresholdIntegral(cv::Mat &inputMat, cv::Mat &outputMat, float T, int part)
1722
CV_Assert(outputMat.channels() == 1);
1823

1924
// rows -> height -> y
20-
int nRows = inputMat.rows;
25+
nRows = inputMat.rows;
2126
// cols -> width -> x
22-
int nCols = inputMat.cols;
27+
nCols = inputMat.cols;
2328

2429
// create the integral image
25-
cv::Mat sumMat;
2630
cv::integral(inputMat, sumMat);
2731

2832
CV_Assert(sumMat.depth() == CV_32S);
2933
CV_Assert(sizeof(int) == 4);
3034

31-
int S = MAX(nRows, nCols) / part;
35+
S = MAX(nRows, nCols);
36+
S = (S > (part + part)) ? (S / part) : 2;
3237

3338
// perform thresholding
34-
int s2 = S/2;
35-
int x1, y1, x2, y2, count, sum;
36-
37-
// CV_Assert(sizeof(int) == 4);
38-
int *p_y1, *p_y2;
39-
uchar *p_inputMat, *p_outputMat;
39+
s2 = S/2;
4040

41-
for( int i = 0; i < nRows; ++i)
41+
for(i = 0; i < nRows; ++i)
4242
{
43-
y1 = i-s2;
44-
y2 = i+s2;
45-
46-
if (y1 < 0){
47-
y1 = 0;
48-
}
49-
if (y2 >= nRows) {
50-
y2 = nRows-1;
51-
}
43+
y1 = (i < s2) ? 0 : (i - s2);
44+
y2 = ((i + s2) < nRows) ? (i + s2) : (nRows - 1);
5245

5346
p_y1 = sumMat.ptr<int>(y1);
5447
p_y2 = sumMat.ptr<int>(y2);
5548
p_inputMat = inputMat.ptr<uchar>(i);
5649
p_outputMat = outputMat.ptr<uchar>(i);
5750

58-
for ( int j = 0; j < nCols; ++j)
51+
for (j = 0; j < nCols; ++j)
5952
{
60-
// set the SxS region
61-
x1 = j-s2;
62-
x2 = j+s2;
53+
x1 = (j < s2) ? 0 : (j - s2);
54+
x2 = ((j + s2) < nCols) ? (j + s2) : (nCols - 1);
6355

64-
if (x1 < 0) {
65-
x1 = 0;
66-
}
67-
if (x2 >= nCols) {
68-
x2 = nCols-1;
69-
}
70-
71-
count = (x2-x1)*(y2-y1);
56+
count = (x2 - x1) * (y2 - y1);
7257

7358
// I(x,y)=s(x2,y2)-s(x1,y2)-s(x2,y1)+s(x1,x1)
7459
sum = p_y2[x2] - p_y1[x2] - p_y2[x1] + p_y1[x1];
7560

76-
if ((int)(p_inputMat[j] * count) < (int)(sum * (1.0f - T)))
77-
p_outputMat[j] = 0;
78-
else
79-
p_outputMat[j] = 255;
61+
ip = (int)(p_inputMat[j] * count);
62+
it = (int)(sum * (1.0f - T));
63+
p_outputMat[j] = (ip < it) ? 0 : 255;
8064
}
8165
}
8266
}
8367

84-
8568
int main(int argc, char *argv[])
8669
{
8770
float T = 0.15f;
88-
int part = 8;
71+
int part = 8, blur = 0;
8972
printf("Adaptive Integral Threshold.\n");
9073
if (argc < 3)
9174
{
92-
printf("Usage: aithreshold image_in image_out [T=0.15] [part=8]\n");
75+
printf("Usage: aithreshold image_in image_out [T=0.15] [part=8] [blur=0]\n");
9376
return 0;
9477
}
9578
// Load the image
9679
cv::Mat src = cv::imread(argv[1]);
97-
if (argc > 3)
98-
{
99-
T = atof(argv[3]);
100-
}
101-
if (argc > 4)
102-
{
103-
part = atoi(argv[4]);
104-
}
80+
if (argc > 3) T = atof(argv[3]);
81+
if (argc > 4) part = atoi(argv[4]);
82+
if (argc > 5) blur = atoi(argv[5]);
10583

10684
// Check if image is loaded fine
10785
if(src.empty()) {
@@ -121,11 +99,14 @@ int main(int argc, char *argv[])
12199
gray = src;
122100
}
123101

102+
printf("T: %f, part: %d, blur: %d\n", T, part, blur);
103+
blur++;
104+
if (blur > 1) cv::blur(gray, gray, cv::Size(blur, blur));
124105
cv::Mat bw2 = cv::Mat::zeros(gray.size(), CV_8UC1);
125106
thresholdIntegral(gray, bw2, T, part);
126107
printf("%s -> %s\n", argv[1], argv[2]);
127108

128109
// Write threshold image
129-
cv::imwrite(argv[2],bw2);
110+
cv::imwrite(argv[2], bw2);
130111
return 0;
131112
}

0 commit comments

Comments
 (0)