code_device/hgdriver/ImageProcess/ImageApplyUVMerge.cpp

187 lines
5.6 KiB
C++

#include "ImageApplyUVMerge.h"
#include "ImageProcess_Public.h"
using namespace cv;
#define SCA 50
CImageApplyUVMerge::CImageApplyUVMerge(): lut(1, 256, CV_8UC1)
{
}
CImageApplyUVMerge::~CImageApplyUVMerge()
{
}
void CImageApplyUVMerge::update_lutData(int contrast)
{
unsigned char* ptr = lut.data;
int m_contrast = cv::max(-127, cv::min(contrast, 127));
for (int i = 0; i < 256; i++)
{
//update contrast
if (i < 128)
ptr[i] = static_cast<unsigned char>(cv::max(0, cv::min(i - m_contrast, 127)));
else
ptr[i] = static_cast<unsigned char>(cv::max(127, cv::min(i + m_contrast, 255)));
}
}
void CImageApplyUVMerge::Apply(cv::Mat& image, const cv::Mat& uv, int dpi, int thresh)
{
update_lutData(12);
cv::LUT(uv, lut, uv);
Mat uv_resize;
cv::resize(uv, uv_resize, cv::Size(uv.cols * SCA / dpi, uv.rows * SCA / dpi));
if (uv_resize.channels() == 3)
cv::cvtColor(uv_resize, uv_resize, cv::COLOR_BGR2GRAY);
cv::threshold(uv_resize, uv_resize, 0, 255, THRESH_OTSU);
cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(1500 / dpi, 1500 / dpi));
cv::dilate(uv_resize, uv_resize, element);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> hierarchy;
hg::findContours(uv_resize, contours, hierarchy, cv::RETR_EXTERNAL);
std::map<int, cv::Scalar> map_color;
for (int i = 0; i < contours.size(); i++)
{
cv::Rect roi = cv::boundingRect(contours[i]);
roi.x *= dpi / SCA;
roi.y *= dpi / SCA;
roi.width *= dpi / SCA;
roi.height *= dpi / SCA;
purgeQR_kernal(image, roi, map_color, dpi, thresh);
}
}
cv::Mat CImageApplyUVMerge::Apply(const cv::Mat& image, const cv::Mat& uv, const cv::RotatedRect& uvRoi, bool isDesaskew, int angle)
{
if (uvRoi.size.width == 0) return cv::Mat();
cv::RotatedRect uvRoi_clone = uvRoi;
cv::Mat dst = cv::Mat::zeros(image.rows > image.cols ? image.rows : (image.rows * 2), image.cols > image.rows ? image.cols : (image.cols * 2), image.type());
image.copyTo(dst(cv::Rect(0, 0, image.cols, image.rows)));
cv::Mat dst_uv = dst(cv::Rect(image.rows > image.cols ? image.cols : 0, image.rows > image.cols ? 0 : image.rows, image.cols, image.rows));
if (isDesaskew)
{
cv::Point2f srcTri[4];
cv::Point2f dstTri[3];
uvRoi_clone.points(srcTri);
if (angle == 90)
{
dstTri[0] = cv::Point2f(0, 0);
dstTri[1] = cv::Point2f(dst_uv.cols - 1, 0);
dstTri[2] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
}
else if (angle == 180)
{
dstTri[0] = cv::Point2f(dst_uv.cols - 1, 0);
dstTri[1] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
dstTri[2] = cv::Point2f(0, dst_uv.rows - 1);
}
else if (angle == 270)
{
dstTri[0] = cv::Point2f(dst_uv.cols - 1, dst_uv.rows - 1);
dstTri[1] = cv::Point2f(0, dst_uv.rows - 1);
dstTri[2] = cv::Point2f(0, 0);
}
else
{
dstTri[0] = cv::Point2f(0, dst_uv.rows - 1);
dstTri[1] = cv::Point2f(0, 0);
dstTri[2] = cv::Point2f(dst_uv.cols - 1, 0);
}
cv::Mat warp_mat = cv::getAffineTransform(srcTri, dstTri);
if (uv.channels() == 1 && dst_uv.channels() == 3)
{
cv::Mat uv_temp;
cv::warpAffine(uv, uv_temp, warp_mat, dst_uv.size());
cv::cvtColor(uv_temp, dst_uv, cv::COLOR_GRAY2BGR);
}
else
cv::warpAffine(uv, dst_uv, warp_mat, dst_uv.size());
}
else
{
cv::Rect uvBoundingRect = uvRoi_clone.boundingRect();
cv::Rect roi_dst_right;
roi_dst_right.x = dst_uv.cols > uvBoundingRect.width ? (dst_uv.cols - uvBoundingRect.width) / 2 : 0;
roi_dst_right.width = cv::min(dst_uv.cols, uvBoundingRect.width);
roi_dst_right.y = dst_uv.rows > uvBoundingRect.height ? (dst_uv.rows - uvBoundingRect.height) / 2 : 0;
roi_dst_right.height = cv::min(dst_uv.rows, uvBoundingRect.height);
cv::Rect roi_uv_BoundingRect((uvBoundingRect.width - roi_dst_right.width) / 2,
(uvBoundingRect.height - roi_dst_right.height) / 2, roi_dst_right.width, roi_dst_right.height);
Mat uvCrop = (uv(uvBoundingRect))(roi_uv_BoundingRect);
if (uvCrop.channels() == 1 && dst_uv.channels() == 3)
cv::cvtColor(uvCrop, uvCrop, cv::COLOR_GRAY2BGR);
uvCrop.copyTo(dst_uv(roi_dst_right));
}
return dst;
}
void CImageApplyUVMerge::purgeQR_kernal(cv::Mat& image, const cv::Rect& roi, std::map<int, cv::Scalar> map_color, int dpi, int threshold)
{
cv::Mat image_roi = image(roi);
cv::Mat mask;
cv::cvtColor(image_roi, mask, cv::COLOR_BGR2GRAY);
cv::threshold(mask, mask, 127, 255, cv::THRESH_OTSU);
cv::Mat image_resize;
cv::resize(image, image_resize, cv::Size(image.cols, 800));
for (int i = 0, cols = image_roi.cols, rows = image_roi.rows; i < cols; i++)
{
cv::Scalar color_fill;
if (map_color.find(i + roi.x) == map_color.end())
{
color_fill = getColor(image_resize, roi.x + i, threshold);
map_color[i + roi.x] = color_fill;
}
else
color_fill = map_color[i + roi.x];
for (int j = 0; j < rows; j++)
{
if (*mask.ptr<uchar>(j, i))
{
uchar* color = image_roi.ptr<uchar>(j, i);
color[0] = color_fill[0];
color[1] = color_fill[1];
color[2] = color_fill[2];
}
}
}
}
cv::Scalar CImageApplyUVMerge::getColor(const cv::Mat& image, int col, int threshold)
{
cv::Scalar color(0, 0, 0);
int num = 0;
for (int i = 0, length = image.rows; i < length; i++)
{
const uchar* ptr = image.ptr<uchar>(i, col);
int gray = (ptr[0] * 30 + ptr[1] * 59 + ptr[2] * 11) / 100;
if (gray > threshold)
{
color[0] += ptr[0];
color[1] += ptr[1];
color[2] += ptr[2];
num++;
}
}
if (num)
color /= num;
else
color[0] = color[1] = color[2] = 255;
return color;
}