Return bytes array if UTF-8 decoding failed

This commit is contained in:
Dmitry Kurtaev 2023-10-03 11:17:00 +03:00
parent 9f7793cdae
commit e0ca191b05
5 changed files with 54 additions and 3 deletions

View File

@ -808,6 +808,13 @@ public:
*/
CV_WRAP std::string detectAndDecodeCurved(InputArray img, OutputArray points=noArray(),
OutputArray straight_qrcode = noArray());
/** @brief Returns a kid of encoding for the decoded info from the latest QR codes
@param codeIdx an index of the previously decoded QR code.
When @ref decode or @ref detectAndDecode is used, valid value is zero.
For @ref decodeMulti or @ref detectAndDecodeMulti use indices corresponding to the output order.
*/
CV_WRAP QRCodeEncoder::ECIEncodings getEncoding(size_t codeIdx = 0);
};
class CV_EXPORTS_W_SIMPLE QRCodeDetectorAruco : public GraphicalCodeDetector {

View File

@ -7,4 +7,31 @@ typedef QRCodeEncoder::Params QRCodeEncoder_Params;
typedef HOGDescriptor::HistogramNormType HOGDescriptor_HistogramNormType;
typedef HOGDescriptor::DescriptorStorageFormat HOGDescriptor_DescriptorStorageFormat;
static PyObject* pyopencv_cv_GraphicalCodeDetector_detectAndDecode(PyObject* self, PyObject* py_args, PyObject* kw);
static PyObject* pyopencv_cv_GraphicalCodeDetector_detectAndDecodeECI(PyObject* self, PyObject* py_args, PyObject* kw) {
// Run original method
PyObject* retval = pyopencv_cv_GraphicalCodeDetector_detectAndDecode(self, py_args, kw);
if (PyErr_Occurred()) {
PyObject *type = nullptr, *value = nullptr, *traceback = nullptr;
PyErr_Fetch(&type, &value, &traceback);
PyObject* object = PyUnicodeDecodeError_GetObject(value);
if (object && PyBytes_Check(object)) {
// TODO: use getEncoding. For now return just bytes array.
PyTuple_SetItem(retval, 0, object);
// PyObject* decoded = PyUnicode_FromEncodedObject(object, "ISO-8859-1", NULL);
// PyTuple_SetItem(retval, 0, decoded);
} else {
PyErr_Restore(type, value, traceback);
}
}
return retval;
}
// TODO: copy docstring somehow
#define PYOPENCV_EXTRA_METHODS_GraphicalCodeDetector \
{"detectAndDecode", CV_PY_FN_WITH_KW_(pyopencv_cv_GraphicalCodeDetector_detectAndDecodeECI, 0), "detectAndDecode(img[, points[, straight_code]]) -> retval, points, straight_code\n. @brief Both detects and decodes graphical code\n. \n. @param img grayscale or color (BGR) image containing graphical code.\n. @param points optional output array of vertices of the found graphical code quadrangle, will be empty if not found.\n. @param straight_code The optional output image containing binarized code"},
#endif

View File

@ -963,6 +963,7 @@ public:
double epsX, epsY;
mutable vector<vector<Point2f>> alignmentMarkers;
mutable vector<Point2f> updateQrCorners;
mutable vector<QRCodeEncoder::ECIEncodings> encodings;
bool useAlignmentMarkers = true;
bool detect(InputArray in, OutputArray points) const override;
@ -978,6 +979,8 @@ public:
String decodeCurved(InputArray in, InputArray points, OutputArray straight_qrcode);
std::string detectAndDecodeCurved(InputArray in, OutputArray points, OutputArray straight_qrcode);
QRCodeEncoder::ECIEncodings getEncoding(size_t codeIdx);
};
QRCodeDetector::QRCodeDetector() {
@ -994,6 +997,12 @@ QRCodeDetector& QRCodeDetector::setEpsY(double epsY) {
return *this;
}
QRCodeEncoder::ECIEncodings QRCodeDetector::getEncoding(size_t codeIdx) {
auto& encodings = std::dynamic_pointer_cast<ImplContour>(p)->encodings;
CV_Assert(codeIdx < encodings.size());
return encodings[codeIdx];
}
bool ImplContour::detect(InputArray in, OutputArray points) const
{
Mat inarr;
@ -1035,6 +1044,8 @@ public:
uint8_t total_num = 1;
} structure_info;
QRCodeEncoder::ECIEncodings eci;
protected:
double getNumModules();
Mat getHomography() {
@ -2802,7 +2813,6 @@ static std::string encodeUTF8_bytesarray(const uint8_t* str, const size_t size)
bool QRDecode::decodingProcess()
{
QRCodeEncoder::ECIEncodings eci;
const uint8_t* payload;
size_t payload_len;
#ifdef HAVE_QUIRC
@ -2966,6 +2976,7 @@ std::string ImplContour::decode(InputArray in, InputArray points, OutputArray st
alignmentMarkers = {qrdec.alignment_coords};
updateQrCorners = qrdec.getOriginalPoints();
}
encodings.resize(1, qrdec.encoding);
return ok ? decoded_info : std::string();
}
@ -2999,6 +3010,7 @@ String ImplContour::decodeCurved(InputArray in, InputArray points, OutputArray s
{
qrdec.getStraightBarcode().convertTo(straight_qrcode, CV_8UC1);
}
encodings.resize(1, qrdec.encoding);
return ok ? decoded_info : std::string();
}

View File

@ -739,14 +739,16 @@ bool pyopencv_to(PyObject* obj, String &value, const ArgInfo& info)
template<>
PyObject* pyopencv_from(const String& value)
{
return PyString_FromString(value.empty() ? "" : value.c_str());
PyObject* ret = PyString_FromString(value.empty() ? "" : value.c_str());
return ret ? ret : Py_None;
}
#if CV_VERSION_MAJOR == 3
template<>
PyObject* pyopencv_from(const std::string& value)
{
return PyString_FromString(value.empty() ? "" : value.c_str());
PyObject* ret = PyString_FromString(value.empty() ? "" : value.c_str());
return ret ? ret : Py_None;
}
#endif

View File

@ -133,6 +133,9 @@ static PyGetSetDef pyopencv_${name}_getseters[] =
static PyMethodDef pyopencv_${name}_methods[] =
{
#ifdef PYOPENCV_EXTRA_METHODS_${name}
PYOPENCV_EXTRA_METHODS_${name}
#endif
${methods_inits}
{NULL, NULL}
};