Skip to content

Commit d634672

Browse files
committed
~ Added white on black mode for the adaptive binarization methods.
It should be enabled when the text or content is lighter than the background.
1 parent d7ab455 commit d634672

9 files changed

+160
-104
lines changed

filters/output/BlackWhiteOptions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ namespace output {
3030
wolfLowerBound(1),
3131
wolfUpperBound(254),
3232
wolfCoef(0.3),
33+
whiteOnBlackMode(false),
3334
binarizationMethod(OTSU) {
3435
}
3536

@@ -43,6 +44,7 @@ namespace output {
4344
wolfLowerBound(el.attribute("wolfLowerBound").toInt()),
4445
wolfUpperBound(el.attribute("wolfUpperBound").toInt()),
4546
wolfCoef(el.attribute("wolfCoef").toDouble()),
47+
whiteOnBlackMode(el.attribute("whiteOnBlackMode") == "1"),
4648
binarizationMethod(parseBinarizationMethod(el.attribute("binarizationMethod"))) {
4749
}
4850

@@ -57,6 +59,7 @@ namespace output {
5759
el.setAttribute("wolfLowerBound", wolfLowerBound);
5860
el.setAttribute("wolfUpperBound", wolfUpperBound);
5961
el.setAttribute("wolfCoef", wolfCoef);
62+
el.setAttribute("whiteOnBlackMode", whiteOnBlackMode ? "1" : "0");
6063
el.setAttribute("binarizationMethod", formatBinarizationMethod(binarizationMethod));
6164

6265
return el;
@@ -72,6 +75,7 @@ namespace output {
7275
&& (wolfLowerBound == other.wolfLowerBound)
7376
&& (wolfUpperBound == other.wolfUpperBound)
7477
&& (wolfCoef == other.wolfCoef)
78+
&& (whiteOnBlackMode == other.whiteOnBlackMode)
7579
&& (binarizationMethod == other.binarizationMethod);
7680
}
7781

@@ -134,6 +138,14 @@ namespace output {
134138
void BlackWhiteOptions::setWolfCoef(double wolfCoef) {
135139
BlackWhiteOptions::wolfCoef = wolfCoef;
136140
}
141+
142+
bool BlackWhiteOptions::isWhiteOnBlackMode() const {
143+
return whiteOnBlackMode;
144+
}
145+
146+
void BlackWhiteOptions::setWhiteOnBlackMode(bool whiteOnBlackMode) {
147+
BlackWhiteOptions::whiteOnBlackMode = whiteOnBlackMode;
148+
}
137149

138150
BlackWhiteOptions::BinarizationMethod BlackWhiteOptions::getBinarizationMethod() const {
139151
return binarizationMethod;

filters/output/BlackWhiteOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ namespace output {
8686

8787
void setWolfCoef(double wolfCoef);
8888

89+
bool isWhiteOnBlackMode() const;
90+
91+
void setWhiteOnBlackMode(bool whiteOnBlackMode);
92+
8993
BinarizationMethod getBinarizationMethod() const;
9094

9195
void setBinarizationMethod(BinarizationMethod binarizationMethod);
@@ -104,6 +108,7 @@ namespace output {
104108
int wolfLowerBound;
105109
int wolfUpperBound;
106110
double wolfCoef;
111+
bool whiteOnBlackMode;
107112
BinarizationMethod binarizationMethod;
108113
};
109114
}

filters/output/OutputGenerator.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,24 +1710,40 @@ namespace output {
17101710
}
17111711

17121712
BinaryImage OutputGenerator::binarize(QImage const& image) const {
1713+
if ((image.format() == QImage::Format_Mono)
1714+
|| (image.format() == QImage::Format_MonoLSB)) {
1715+
return BinaryImage(image);
1716+
}
1717+
17131718
BlackWhiteOptions blackWhiteOptions = m_colorParams.blackWhiteOptions();
17141719
BlackWhiteOptions::BinarizationMethod binarizationMethod = blackWhiteOptions.getBinarizationMethod();
17151720

1721+
QImage imageToBinarize = image;
1722+
17161723
BinaryImage binarized;
17171724
switch (binarizationMethod) {
17181725
case BlackWhiteOptions::OTSU: {
1719-
GrayscaleHistogram hist(image);
1726+
GrayscaleHistogram hist(imageToBinarize);
17201727
BinaryThreshold const bw_thresh(BinaryThreshold::otsuThreshold(hist));
17211728

1722-
binarized = BinaryImage(image, adjustThreshold(bw_thresh));
1729+
binarized = BinaryImage(imageToBinarize, adjustThreshold(bw_thresh));
17231730
break;
17241731
}
17251732
case BlackWhiteOptions::SAUVOLA: {
17261733
QSize windowsSize = QSize(blackWhiteOptions.getWindowSize(),
17271734
blackWhiteOptions.getWindowSize());
17281735
double sauvolaCoef = blackWhiteOptions.getSauvolaCoef();
17291736

1730-
binarized = imageproc::binarizeSauvola(image, windowsSize, sauvolaCoef);
1737+
if (blackWhiteOptions.isWhiteOnBlackMode()) {
1738+
imageToBinarize = imageproc::toGrayscale(imageToBinarize);
1739+
imageToBinarize.invertPixels();
1740+
}
1741+
1742+
binarized = imageproc::binarizeSauvola(imageToBinarize, windowsSize, sauvolaCoef);
1743+
1744+
if (blackWhiteOptions.isWhiteOnBlackMode()) {
1745+
binarized.invert();
1746+
}
17311747
break;
17321748
}
17331749
case BlackWhiteOptions::WOLF: {
@@ -1737,7 +1753,16 @@ namespace output {
17371753
unsigned char upperBound = (unsigned char) blackWhiteOptions.getWolfUpperBound();
17381754
double wolfCoef = blackWhiteOptions.getWolfCoef();
17391755

1740-
binarized = imageproc::binarizeWolf(image, windowsSize, lowerBound, upperBound, wolfCoef);
1756+
if (blackWhiteOptions.isWhiteOnBlackMode()) {
1757+
imageToBinarize = imageproc::toGrayscale(imageToBinarize);
1758+
imageToBinarize.invertPixels();
1759+
}
1760+
1761+
binarized = imageproc::binarizeWolf(imageToBinarize, windowsSize, lowerBound, upperBound, wolfCoef);
1762+
1763+
if (blackWhiteOptions.isWhiteOnBlackMode()) {
1764+
binarized.invert();
1765+
}
17411766
break;
17421767
}
17431768
}

filters/output/SauvolaBinarizationOptionsWidget.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ namespace output {
2424
&delayedStateChanger, SIGNAL(timeout()),
2525
this, SLOT(sendStateChanged())
2626
);
27+
connect(
28+
whiteOnBlackModeCB, SIGNAL(clicked(bool)),
29+
this, SLOT(whiteOnBlackModeToggled(bool))
30+
);
2731
}
2832

2933
void SauvolaBinarizationOptionsWidget::preUpdateUI(PageId const& page_id) {
@@ -52,10 +56,19 @@ namespace output {
5256
delayedStateChanger.start(750);
5357
}
5458

59+
void SauvolaBinarizationOptionsWidget::whiteOnBlackModeToggled(bool checked) {
60+
BlackWhiteOptions opt(m_colorParams.blackWhiteOptions());
61+
opt.setWhiteOnBlackMode(checked);
62+
m_colorParams.setBlackWhiteOptions(opt);
63+
m_ptrSettings->setColorParams(m_pageId, m_colorParams);
64+
emit stateChanged();
65+
}
66+
5567
void SauvolaBinarizationOptionsWidget::updateView() {
5668
BlackWhiteOptions blackWhiteOptions = m_colorParams.blackWhiteOptions();
5769
windowSize->setValue(blackWhiteOptions.getWindowSize());
5870
sauvolaCoef->setValue(blackWhiteOptions.getSauvolaCoef());
71+
whiteOnBlackModeCB->setChecked(blackWhiteOptions.isWhiteOnBlackMode());
5972
}
6073

6174
void SauvolaBinarizationOptionsWidget::sendStateChanged() {

filters/output/SauvolaBinarizationOptionsWidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ namespace output {
3333

3434
void sauvolaCoefChanged(double value);
3535

36+
void whiteOnBlackModeToggled(bool checked);
37+
3638
void sendStateChanged();
3739

3840
private:

filters/output/WolfBinarizationOptionsWidget.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ namespace output {
3232
&delayedStateChanger, SIGNAL(timeout()),
3333
this, SLOT(sendStateChanged())
3434
);
35+
connect(
36+
whiteOnBlackModeCB, SIGNAL(clicked(bool)),
37+
this, SLOT(whiteOnBlackModeToggled(bool))
38+
);
3539
}
3640

3741
void WolfBinarizationOptionsWidget::preUpdateUI(PageId const& page_id) {
@@ -78,12 +82,21 @@ namespace output {
7882
delayedStateChanger.start(750);
7983
}
8084

85+
void WolfBinarizationOptionsWidget::whiteOnBlackModeToggled(bool checked) {
86+
BlackWhiteOptions opt(m_colorParams.blackWhiteOptions());
87+
opt.setWhiteOnBlackMode(checked);
88+
m_colorParams.setBlackWhiteOptions(opt);
89+
m_ptrSettings->setColorParams(m_pageId, m_colorParams);
90+
emit stateChanged();
91+
}
92+
8193
void WolfBinarizationOptionsWidget::updateView() {
8294
BlackWhiteOptions blackWhiteOptions = m_colorParams.blackWhiteOptions();
8395
windowSize->setValue(blackWhiteOptions.getWindowSize());
8496
lowerBound->setValue(blackWhiteOptions.getWolfLowerBound());
8597
upperBound->setValue(blackWhiteOptions.getWolfUpperBound());
8698
wolfCoef->setValue(blackWhiteOptions.getWolfCoef());
99+
whiteOnBlackModeCB->setChecked(blackWhiteOptions.isWhiteOnBlackMode());
87100
}
88101

89102
void WolfBinarizationOptionsWidget::sendStateChanged() {

filters/output/WolfBinarizationOptionsWidget.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ namespace output {
3636

3737
void upperBoundChanged(int value);
3838

39+
void whiteOnBlackModeToggled(bool checked);
40+
3941
void sendStateChanged();
4042

4143
private:

filters/output/ui/SauvolaBinarizationOptionsWidget.ui

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>147</width>
10-
<height>57</height>
9+
<width>166</width>
10+
<height>96</height>
1111
</rect>
1212
</property>
1313
<property name="sizePolicy">
@@ -19,46 +19,38 @@
1919
<property name="windowTitle">
2020
<string>Form</string>
2121
</property>
22-
<layout class="QVBoxLayout" name="verticalLayout">
23-
<property name="spacing">
24-
<number>4</number>
25-
</property>
26-
<property name="leftMargin">
27-
<number>0</number>
28-
</property>
29-
<property name="topMargin">
30-
<number>0</number>
31-
</property>
32-
<property name="rightMargin">
33-
<number>0</number>
34-
</property>
35-
<property name="bottomMargin">
36-
<number>0</number>
37-
</property>
22+
<layout class="QHBoxLayout" name="horizontalLayout">
3823
<item>
39-
<layout class="QHBoxLayout" name="horizontalLayout">
40-
<property name="sizeConstraint">
41-
<enum>QLayout::SetMinimumSize</enum>
24+
<spacer name="horizontalSpacer">
25+
<property name="orientation">
26+
<enum>Qt::Horizontal</enum>
4227
</property>
28+
<property name="sizeHint" stdset="0">
29+
<size>
30+
<width>3</width>
31+
<height>17</height>
32+
</size>
33+
</property>
34+
</spacer>
35+
</item>
36+
<item>
37+
<layout class="QVBoxLayout" name="verticalLayout_2">
4338
<item>
44-
<spacer name="horizontalSpacer">
45-
<property name="orientation">
46-
<enum>Qt::Horizontal</enum>
39+
<widget class="QCheckBox" name="whiteOnBlackModeCB">
40+
<property name="toolTip">
41+
<string>This options should be enabled when the text or content is placed on the darker background</string>
4742
</property>
48-
<property name="sizeHint" stdset="0">
49-
<size>
50-
<width>1</width>
51-
<height>20</height>
52-
</size>
43+
<property name="text">
44+
<string>White on black mode</string>
5345
</property>
54-
</spacer>
46+
</widget>
5547
</item>
5648
<item>
5749
<layout class="QGridLayout" name="gridLayout">
58-
<item row="0" column="0">
59-
<widget class="QLabel" name="windowSizeLabel">
50+
<item row="1" column="0">
51+
<widget class="QLabel" name="sauvolaCoefLabel">
6052
<property name="text">
61-
<string>Window size:</string>
53+
<string>Coef:</string>
6254
</property>
6355
</widget>
6456
</item>
@@ -71,14 +63,14 @@
7163
<number>5</number>
7264
</property>
7365
<property name="maximum">
74-
<number>999</number>
66+
<number>9999</number>
7567
</property>
7668
</widget>
7769
</item>
78-
<item row="1" column="0">
79-
<widget class="QLabel" name="sauvolaCoefLabel">
70+
<item row="0" column="0">
71+
<widget class="QLabel" name="windowSizeLabel">
8072
<property name="text">
81-
<string>Coef:</string>
73+
<string>Window size:</string>
8274
</property>
8375
</widget>
8476
</item>
@@ -100,21 +92,21 @@
10092
</item>
10193
</layout>
10294
</item>
103-
<item>
104-
<spacer name="horizontalSpacer_2">
105-
<property name="orientation">
106-
<enum>Qt::Horizontal</enum>
107-
</property>
108-
<property name="sizeHint" stdset="0">
109-
<size>
110-
<width>1</width>
111-
<height>20</height>
112-
</size>
113-
</property>
114-
</spacer>
115-
</item>
11695
</layout>
11796
</item>
97+
<item>
98+
<spacer name="horizontalSpacer_2">
99+
<property name="orientation">
100+
<enum>Qt::Horizontal</enum>
101+
</property>
102+
<property name="sizeHint" stdset="0">
103+
<size>
104+
<width>3</width>
105+
<height>17</height>
106+
</size>
107+
</property>
108+
</spacer>
109+
</item>
118110
</layout>
119111
</widget>
120112
<resources/>

0 commit comments

Comments
 (0)