sharpen camera image preprocessing, check original and preprocessed camera images

This commit is contained in:
ohsqueezy 2022-09-22 17:20:00 -04:00
parent 5f417a2592
commit 862030b296
5 changed files with 54 additions and 34 deletions

View File

@ -59,8 +59,8 @@
"json-save-directory": "local/scans",
"barcode": "",
"capture-device": "/dev/video0",
"brightness-addition": 10,
"contrast-multiplication": 1.3,
"brightness-addition": 20,
"contrast-multiplication": 1.4,
"camera-device-id": 0
},

View File

@ -1,6 +1,11 @@
<!doctype html>
<html>
<!-- DTD taken from https://www.w3.org/wiki/Choosing_the_right_doctype_for_your_HTML_documents -->
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<!-- Language and charset taken from https://www.w3.org/International/questions/qa-html-encoding-declarations -->
<html lang="en">
<head>
<meta charset="utf-8">
<style>
body
{
@ -8,6 +13,7 @@
}
</style>
</head>
<body>
<!-- WebGL output will be drawn here through Emscripten. The dimensions will be set by Emscripten. -->
<canvas id="canvas"></canvas>

2
lib/sb

@ -1 +1 @@
Subproject commit 24f6d3ed3d4962a88078c5024473834812968d1a
Subproject commit 346a059ee2c98fee814df51b560bbde7e6b733db

View File

@ -780,11 +780,11 @@ void Pudding::web_get_bytes(std::string url, const web_callback& callback, const
Request* request = new Request(callback, url);
requests.push_back(request);
/* Use the CORS anywhere proxy */
url = "https://mario.shampoo.ooo:8088/" + url;
#if defined(__EMSCRIPTEN__)
/* Use the CORS anywhere proxy */
url = CORS_ANYWHERE_PROXY_URL + url;
/* Create a fetch attributes object. Set the callback that will be called when response data is received. Attach the user
* submitted callback to the userData attribute. Set the headers. */
emscripten_fetch_attr_t attr;
@ -1006,9 +1006,7 @@ void Pudding::capture_frame()
new_frame_available = false;
/* Load camera frame data into `cv::Mat` */
time_it("read frame")([&]{
capture >> camera_frame;
});
#else
@ -1021,12 +1019,19 @@ void Pudding::capture_frame()
if (!camera_frame.empty())
{
/* Sharpen image for barcode detection */
float sigma = 1.0f, threshold = 5.0f, amount = 1.0f;
cv::GaussianBlur(camera_frame, blurred, cv::Size(), sigma, sigma);
low_contrast_mask = cv::abs(camera_frame - blurred) < threshold;
sharpened_frame = camera_frame * (1.0f + amount) + blurred * (-amount);
camera_frame.copyTo(sharpened_frame, low_contrast_mask);
/* Brightness and contrast adjustment, see https://docs.opencv.org/2.4.13.7/doc/tutorials/core/basic_linear_transform/basic_linear_transform.html */
int brightness = configuration()["scan"]["brightness-addition"];
float contrast = configuration()["scan"]["contrast-multiplication"];
if (brightness != 0 || contrast != 1.0)
{
camera_frame.convertTo(camera_frame, -1, contrast, brightness);
camera_frame.convertTo(contrasted_frame, -1, contrast, brightness);
}
/* Finished loading into `cv::Mat`, so it is new data that is safe to read. */
@ -1082,32 +1087,40 @@ void Pudding::update()
#endif
camera_view.texture().bind();
/* Fill camera view texture memory with last frame's pixels */
camera_view.texture().load(camera_frame.ptr(), {camera_frame_width, camera_frame_height}, pixel_format, GL_UNSIGNED_BYTE);
/* Frame data has been loaded, so there is not a new frame available anymore. */
new_frame_available = false;
/* Convert to grayscale, for ZBar */
cv::cvtColor(camera_frame, camera_frame, cv::COLOR_BGR2GRAY);
if (configuration()["scan"]["enabled"])
/* Check the original camera frame and the pre-processed ones for barcodes */
for (const cv::Mat& frame : {camera_frame, contrasted_frame, sharpened_frame})
{
zbar::Image query_image(camera_frame.cols, camera_frame.rows, "Y800", static_cast<void*>(camera_frame.data),
camera_frame.cols * camera_frame.rows);
int result = image_scanner.scan(query_image);
if (result > 0)
/* Fill camera view texture memory with last frame's pixels */
camera_view.texture().load(const_cast<cv::Mat&>(frame).ptr(), {camera_frame_width, camera_frame_height}, pixel_format, GL_UNSIGNED_BYTE);
/* Convert to grayscale, for ZBar */
cv::cvtColor(frame, zbar_frame, cv::COLOR_BGR2GRAY);
if (configuration()["scan"]["enabled"])
{
time_it("barcode lookup")([&] {
for (zbar::Image::SymbolIterator symbol = query_image.symbol_begin(); symbol != query_image.symbol_end(); ++symbol)
{
std::ostringstream message;
message << "camera scanned " << symbol->get_type_name() << " symbol " << symbol->get_data();
sb::Log::log(message);
current_camera_barcode = symbol->get_data();
current_barcode = current_camera_barcode;
}
});
zbar::Image query_image(
camera_frame_width, camera_frame_height, "Y800", static_cast<void*>(zbar_frame.data), camera_frame_width * camera_frame_height);
int result = image_scanner.scan(query_image);
if (result > 0)
{
time_it("barcode lookup")([&] {
for (zbar::Image::SymbolIterator symbol = query_image.symbol_begin(); symbol != query_image.symbol_end(); ++symbol)
{
std::ostringstream message;
message << "camera scanned " << symbol->get_type_name() << " symbol " << symbol->get_data();
sb::Log::log(message);
current_camera_barcode = symbol->get_data();
current_barcode = current_camera_barcode;
}
});
/* No need to check the other pre-processed frames */
break;
}
query_image.set_data(nullptr, 0);
}
query_image.set_data(nullptr, 0);
}
/* Frame data has been processed, so there is not a new frame available anymore. */
new_frame_available = false;
}
/* viewport box will be used to tell GL where to draw */

View File

@ -412,6 +412,7 @@ private:
inline static const std::string NUTRITIONIX_NOT_FOUND = "resource not found";
inline static const std::string GOOGLE_BOOKS_API_URL = "https://www.googleapis.com/books/v1/volumes?q=isbn:";
inline static const std::string GIANTBOMB_API_URL = "https://www.giantbomb.com/api/release/?api_key=";
inline static const std::string CORS_ANYWHERE_PROXY_URL = "https://mario.shampoo.ooo:8088/";
inline static const glm::vec3 ZERO_VECTOR_3D {0, 0, 0};
inline static const glm::vec3 Y_UNIT_NORMAL_3D {0, 1, 0};
inline static const glm::mat4 VIEW_MATRIX = glm::lookAt({4.0f, 2.0f, 1.0f}, {0.0f, -0.325f, 0.0f}, Y_UNIT_NORMAL_3D);
@ -428,7 +429,7 @@ private:
#ifndef __EMSCRIPTEN__
cv::VideoCapture capture;
#endif
cv::Mat camera_frame;
cv::Mat camera_frame, contrasted_frame, sharpened_frame, zbar_frame, blurred, low_contrast_mask;
zbar::ImageScanner image_scanner;
std::map<std::string, std::map<std::string, GLuint>> uniform;
GLuint flat_program, mvp_program;