Skip to content

read_number_waterfill: add another parameter line_index for logging purposes, when multithreaded #623

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,24 @@ int read_number(Logger& logger, const ImageViewRGB32& image, Language language){
int read_number_waterfill(
Logger& logger, const ImageViewRGB32& image,
uint32_t rgb32_min, uint32_t rgb32_max,
bool text_inside_range
bool text_inside_range,
int8_t line_index
){
std::string ocr_text = read_number_waterfill_no_normalization(logger, image, rgb32_min, rgb32_max, text_inside_range, UINT32_MAX, false);

std::string normalized = run_number_normalization(ocr_text);

std::string line_index_str = "";
if (line_index != -1){
line_index_str = "Line " + std::to_string(line_index) + ": ";
}
if (normalized.empty()){
logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> Unable to read.", COLOR_RED);
logger.log(line_index_str + "OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> Unable to read.", COLOR_RED);
return -1;
}

int number = std::atoi(normalized.c_str());
logger.log("OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> " + std::to_string(number));
logger.log(line_index_str + "OCR Text: \"" + ocr_text + "\" -> \"" + normalized + "\" -> " + std::to_string(number));

return number;
}
Expand Down Expand Up @@ -192,9 +197,13 @@ int read_number_waterfill_multifilter(
std::vector<std::pair<uint32_t, uint32_t>> filters,
uint32_t width_max,
bool text_inside_range,
bool prioritize_numeric_only_results
bool prioritize_numeric_only_results,
int8_t line_index
){

std::string line_index_str = "";
if (line_index != -1){
line_index_str = "Line " + std::to_string(line_index) + ": ";
}

std::map<int, uint8_t> candidates;
for (std::pair<uint32_t, uint32_t> filter : filters){
Expand All @@ -210,7 +219,7 @@ int read_number_waterfill_multifilter(
}

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

if (prioritize_numeric_only_results && is_digits(ocr_text)){
candidates[candidate] += 2;
Expand All @@ -220,19 +229,19 @@ int read_number_waterfill_multifilter(
}

if (candidates.empty()){
logger.log("No valid OCR candidates. Unable to read number.", COLOR_ORANGE);
logger.log(line_index_str + "No valid OCR candidates. Unable to read number.", COLOR_ORANGE);
return -1;
}

std::pair<int, uint8_t> best;
for (const auto& item : candidates){
logger.log("Candidate " + std::to_string(item.first) + ": " + std::to_string(item.second) + " votes");
logger.log(line_index_str + "Candidate " + std::to_string(item.first) + ": " + std::to_string(item.second) + " votes");
if (item.second > best.second){
best = item;
}
}

logger.log("Best candidate: --------------------------> " + std::to_string(best.first));
logger.log(line_index_str + "Best candidate: --------------------------> " + std::to_string(best.first));
return best.first;
}

Expand Down
10 changes: 8 additions & 2 deletions SerialPrograms/Source/CommonTools/OCR/OCR_NumberReader.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,13 @@ int read_number(Logger& logger, const ImageViewRGB32& image, Language language =
// This version attempts to improve reliability by first isolating each number
// via waterfill. Then it OCRs each number by itself and recombines them at the
// end. This requires specifying the color range for the text.
//
// line_index: specifies the current number's row. for logging purposes, when multithreaded.
int read_number_waterfill(
Logger& logger, const ImageViewRGB32& image,
uint32_t rgb32_min, uint32_t rgb32_max,
bool text_inside_range = true
bool text_inside_range = true,
int8_t line_index = -1
);

// run OCR on each individual character in the string of numbers.
Expand All @@ -53,12 +56,15 @@ int read_number_waterfill(
// prioritize_numeric_only_results:
// - if true: if OCR reads only numeric characters, the candidate gets 2 votes. If OCR reads non-numeric characters, the candidate gets only 1 vote.
// - if false: all reads only get 1 vote
//
// line_index: specifies the current number's row. for logging purposes, when multithreaded.
int read_number_waterfill_multifilter(
Logger& logger, const ImageViewRGB32& image,
std::vector<std::pair<uint32_t, uint32_t>> filters,
uint32_t width_max,
bool text_inside_range = true,
bool prioritize_numeric_only_results = true
bool prioritize_numeric_only_results = true,
int8_t line_index = -1
);


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ void ItemPrinterMaterialDetector::make_overlays(VideoOverlaySet& items) const{

int16_t ItemPrinterMaterialDetector::read_number(
Logger& logger, AsyncDispatcher& dispatcher,
const ImageViewRGB32& screen, const ImageFloatBox& box
const ImageViewRGB32& screen, const ImageFloatBox& box,
int8_t row_index
) const{

ImageViewRGB32 cropped = extract_box_reference(screen, box);
Expand All @@ -98,39 +99,41 @@ int16_t ItemPrinterMaterialDetector::read_number(
bool is_dark_text_light_background = image_stats(filtered).average.sum() > 400;
// std::cout << "Average sum of filtered: "<< std::to_string(image_stats(filtered).average.sum()) << std::endl;

int16_t number;
if (is_dark_text_light_background){
const std::vector<std::pair<uint32_t, uint32_t>> filters = {
// {0xff000000, 0xffb0b0b0},
{0xff000000, 0xffa0a0a0},
{0xff000000, 0xff959595},
{0xff000000, 0xff909090},
{0xff000000, 0xff858585},
{0xff000000, 0xff808080},
// {0xff000000, 0xff707070},
// {0xff000000, 0xff606060},
// {0xff000000, 0xff505050},
// {0xff000000, 0xff404040},
// {0xff000000, 0xff303030},
// {0xff000000, 0xff202020},
// {0xff000000, 0xff101010},
};
number = (int16_t)OCR::read_number_waterfill_multifilter(logger, cropped, filters, 24);
}else{
const std::vector<std::pair<uint32_t, uint32_t>> filters = {
{0xff808080, 0xffffffff},
{0xff858585, 0xffffffff},
{0xff909090, 0xffffffff},
{0xff959595, 0xffffffff},
{0xffa0a0a0, 0xffffffff},
// {0xffb0b0b0, 0xffffffff},
// {0xffc0c0c0, 0xffffffff},
// {0xffd0d0d0, 0xffffffff},
// {0xffe0e0e0, 0xffffffff},
// {0xfff0f0f0, 0xffffffff},
};
number = (int16_t)OCR::read_number_waterfill_multifilter(logger, cropped, filters, 24);
}
const std::vector<std::pair<uint32_t, uint32_t>> filters =
[&](){
if (is_dark_text_light_background){
return std::vector<std::pair<uint32_t, uint32_t>>{
// {0xff000000, 0xffb0b0b0},
{0xff000000, 0xffa0a0a0},
{0xff000000, 0xff959595},
{0xff000000, 0xff909090},
{0xff000000, 0xff858585},
{0xff000000, 0xff808080},
// {0xff000000, 0xff707070},
// {0xff000000, 0xff606060},
// {0xff000000, 0xff505050},
// {0xff000000, 0xff404040},
// {0xff000000, 0xff303030},
// {0xff000000, 0xff202020},
// {0xff000000, 0xff101010},
};
}else{
return std::vector<std::pair<uint32_t, uint32_t>>{
{0xff808080, 0xffffffff},
{0xff858585, 0xffffffff},
{0xff909090, 0xffffffff},
{0xff959595, 0xffffffff},
{0xffa0a0a0, 0xffffffff},
// {0xffb0b0b0, 0xffffffff},
// {0xffc0c0c0, 0xffffffff},
// {0xffd0d0d0, 0xffffffff},
// {0xffe0e0e0, 0xffffffff},
// {0xfff0f0f0, 0xffffffff},
};
}
}();

int16_t number = (int16_t)OCR::read_number_waterfill_multifilter(logger, cropped, filters, 24, true, true, row_index);

if (number < 1 || number > 999){
number = -1;
Expand Down Expand Up @@ -225,7 +228,7 @@ std::vector<int8_t> ItemPrinterMaterialDetector::find_material_value_row_index(
std::vector<std::unique_ptr<AsyncTask>> tasks(total_rows);
for (int8_t row_index = 0; row_index < total_rows; row_index++){
tasks[row_index] = dispatcher.dispatch([&, row_index]{
int16_t value = read_number(stream.logger(), dispatcher, snapshot, m_box_mat_value[row_index]);
int16_t value = read_number(stream.logger(), dispatcher, snapshot, m_box_mat_value[row_index], row_index);
if (value == material_value){
WriteSpinLock lg(lock);
row_indexes.push_back(row_index);
Expand All @@ -246,7 +249,7 @@ int16_t ItemPrinterMaterialDetector::detect_material_quantity(
) const{
context.wait_for_all_requests();
VideoSnapshot snapshot = stream.video().snapshot();
int16_t value = read_number(stream.logger(), dispatcher, snapshot, m_box_mat_quantity[row_index]);
int16_t value = read_number(stream.logger(), dispatcher, snapshot, m_box_mat_quantity[row_index], row_index);
return value;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ class ItemPrinterMaterialDetector{

int16_t read_number(
Logger& logger, AsyncDispatcher& dispatcher,
const ImageViewRGB32& screen, const ImageFloatBox& box
const ImageViewRGB32& screen, const ImageFloatBox& box,
int8_t row_index
) const;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ std::array<int16_t, 10> ItemPrinterPrizeReader::read_quantity(
// filtered.save("DebugDumps/test"+ std::to_string(i) +".png");

tasks[i] = dispatcher.dispatch([&, i]{
results[i] = read_number(logger, screen, boxes[i]);
results[i] = read_number(logger, screen, boxes[i], (int8_t)i);
});
}

Expand All @@ -179,11 +179,12 @@ std::array<int16_t, 10> ItemPrinterPrizeReader::read_quantity(
int16_t ItemPrinterPrizeReader::read_number(
Logger& logger,
const ImageViewRGB32& screen,
const ImageFloatBox& box
const ImageFloatBox& box,
int8_t line_index
) const{

ImageViewRGB32 cropped = extract_box_reference(screen, box);
int16_t number = (int16_t)OCR::read_number_waterfill(logger, cropped, 0xff808000, 0xffffffff);
int16_t number = (int16_t)OCR::read_number_waterfill(logger, cropped, 0xff808000, 0xffffffff, true, line_index);

if (number < 1 || number > 40){
number = 1; // default to 1 if we can't read the prize quantity
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class ItemPrinterPrizeReader{
int16_t read_number(
Logger& logger,
const ImageViewRGB32& screen,
const ImageFloatBox& box
const ImageFloatBox& box,
int8_t line_index = -1
) const;

double average_sum_filtered(const ImageViewRGB32& screen, const ImageFloatBox& box) const;
Expand Down