Skip to content

Commit 7ae3a71

Browse files
committed
Parallelize the multi-filtering.
1 parent c76049f commit 7ae3a71

File tree

3 files changed

+65
-43
lines changed

3 files changed

+65
-43
lines changed

Common/Cpp/Concurrency/AsyncTask.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
*
55
*/
66

7+
#include "SpinPause.h"
78
#include "AsyncTask.h"
89

910
//#include <iostream>
@@ -29,7 +30,7 @@ AsyncTask::~AsyncTask(){
2930
}
3031

3132
while (m_state.load(std::memory_order_acquire) != State::SAFE_TO_DESTRUCT){
32-
// pause
33+
pause();
3334
}
3435

3536
// cout << "Late Finish" << endl;

SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,13 @@
77
#include <algorithm>
88
#include <map>
99
#include "Common/Cpp/AbstractLogger.h"
10+
#include "Common/Cpp/Concurrency/SpinLock.h"
1011
#include "Common/Qt/StringToolsQt.h"
1112
#include "Kernels/Waterfill/Kernels_Waterfill_Session.h"
1213
#include "CommonFramework/Language.h"
1314
#include "CommonFramework/ImageTypes/ImageRGB32.h"
1415
#include "CommonFramework/ImageTools/ImageBoxes.h"
16+
#include "CommonFramework/Tools/GlobalThreadPools.h"
1517
#include "CommonTools/Images/ImageManip.h"
1618
#include "CommonTools/Images/ImageFilter.h"
1719
#include "CommonTools/Images/BinaryImage_FilterRgb32.h"
@@ -218,35 +220,42 @@ int read_number_waterfill_multifilter(
218220
line_index_str = "Line " + std::to_string(line_index) + ": ";
219221
}
220222

223+
SpinLock lock;
221224
std::map<int, uint8_t> candidates;
222-
for (std::pair<uint32_t, uint32_t> filter : filters){
223-
224-
uint32_t rgb32_min = filter.first;
225-
uint32_t rgb32_max = filter.second;
226-
std::string ocr_text = read_number_waterfill_no_normalization(
227-
logger,
228-
image,
229-
rgb32_min, rgb32_max,
230-
text_inside_range,
231-
width_max,
232-
true
233-
);
234-
235-
std::string normalized = run_number_normalization(ocr_text);
236-
if (normalized.empty()){
237-
// logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> Unable to read.", COLOR_RED);
238-
continue;
239-
}
225+
GlobalThreadPools::normal_inference().run_in_parallel(
226+
[&](size_t index){
227+
std::pair<uint32_t, uint32_t> filter = filters[index];
228+
229+
uint32_t rgb32_min = filter.first;
230+
uint32_t rgb32_max = filter.second;
231+
std::string ocr_text = read_number_waterfill_no_normalization(
232+
logger,
233+
image,
234+
rgb32_min, rgb32_max,
235+
text_inside_range,
236+
width_max,
237+
true
238+
);
239+
240+
std::string normalized = run_number_normalization(ocr_text);
241+
if (normalized.empty()){
242+
// logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> Unable to read.", COLOR_RED);
243+
return;
244+
}
240245

241-
int candidate = std::atoi(normalized.c_str());
242-
logger.log(line_index_str + "OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> " + std::to_string(candidate));
246+
int candidate = std::atoi(normalized.c_str());
247+
logger.log(line_index_str + "OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> " + std::to_string(candidate));
243248

244-
if (prioritize_numeric_only_results && is_digits(ocr_text)){
245-
candidates[candidate] += 2;
246-
}else{
247-
candidates[candidate]++;
248-
}
249-
}
249+
uint8_t weight = prioritize_numeric_only_results && is_digits(ocr_text)
250+
? 2
251+
: 1;
252+
253+
WriteSpinLock lg(lock);
254+
candidates[candidate] += weight;
255+
256+
},
257+
0, filters.size(), 1
258+
);
250259

251260
if (candidates.empty()){
252261
logger.log(line_index_str + "No valid OCR candidates. Unable to read number.", COLOR_ORANGE);

SerialPrograms/Source/CommonTools/OCR/OCR_Routines.cpp

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include "CommonFramework/ImageTypes/ImageRGB32.h"
8+
#include "CommonFramework/Tools/GlobalThreadPools.h"
89
#include "CommonTools/Images/ImageFilter.h"
910
#include "OCR_RawOCR.h"
1011
#include "OCR_DictionaryMatcher.h"
@@ -35,24 +36,35 @@ StringMatchResult multifiltered_OCR(
3536
double pixels_inv = 1. / (image.width() * image.height());
3637

3738
// Run all the filters.
39+
SpinLock lock;
3840
StringMatchResult ret;
41+
GlobalThreadPools::normal_inference().run_in_parallel(
42+
[&](size_t index){
43+
const std::pair<ImageRGB32, size_t>& filtered = filtered_images[index];
44+
45+
std::string text = ocr_read(language, filtered.first);
46+
// cout << text.toStdString() << endl;
47+
// filtered.first.save("test" + QString::number(c++) + ".png");
48+
49+
// Compute ratio of image that matches text color. Skip if it's out of range.
50+
double ratio = filtered.second * pixels_inv;
51+
// cout << "ratio = " << ratio << endl;
52+
if (ratio < min_text_ratio || ratio > max_text_ratio){
53+
return;
54+
}
55+
56+
StringMatchResult current = dictionary.match_substring(language, text, log10p_spread);
57+
58+
WriteSpinLock lg(lock);
59+
ret.exact_match |= current.exact_match;
60+
ret.results.insert(current.results.begin(), current.results.end());
61+
62+
},
63+
0, filtered_images.size(), 1
64+
);
3965
// int c = 0;
40-
for (const auto& filtered : filtered_images){
41-
std::string text = ocr_read(language, filtered.first);
42-
// cout << text.toStdString() << endl;
43-
// filtered.first.save("test" + QString::number(c++) + ".png");
44-
45-
// Compute ratio of image that matches text color. Skip if it's out of range.
46-
double ratio = filtered.second * pixels_inv;
47-
// cout << "ratio = " << ratio << endl;
48-
if (ratio < min_text_ratio || ratio > max_text_ratio){
49-
continue;
50-
}
51-
52-
StringMatchResult current = dictionary.match_substring(language, text, log10p_spread);
53-
ret.exact_match |= current.exact_match;
54-
ret.results.insert(current.results.begin(), current.results.end());
55-
}
66+
// for (const auto& filtered : filtered_images){
67+
// }
5668

5769
// ret.log(global_logger_tagged(), -1.5);
5870

0 commit comments

Comments
 (0)