twain2/hugaotwainds/ImageApplyDiscardBlank.cpp

175 lines
4.3 KiB
C++
Raw Normal View History

2020-03-11 02:53:30 +00:00
#include "StdAfx.h"
#include "ImageApplyDiscardBlank.h"
#include "ImageProcess_Public.h"
CImageApplyDiscardBlank::CImageApplyDiscardBlank(bool isnormal)
: m_res(false)
, isNormalDiscard(isnormal)
, dSize(200)
, devTh(15, 15, 15, 15)
{
}
CImageApplyDiscardBlank::~CImageApplyDiscardBlank(void)
{
}
int CImageApplyDiscardBlank::processRectR(const cv::Mat& image, cv::RotatedRect& rotatedRect, std::vector<cv::Point>& maxContour,
double scale, double thresh, int blobAreaSize)
{
cv::Mat gray;
int blockCount = 0;
if (image.channels() == 3)
if (scale != 1.0f)
{
cv::Size ResImgSiz = cv::Size(image.cols * scale, image.rows * scale);
resize(image, gray, cv::Size(), scale, scale, 0);
cvtColor(gray, gray, CV_BGR2GRAY);
}
else
cvtColor(image, gray, CV_BGR2GRAY);
else
if (scale != 1.0f)
resize(image, gray, cv::Size(), scale, scale, 0);
else
gray = image;
cv::Mat threshold_img;
threshold(gray, threshold_img, thresh, 255.0, CV_THRESH_BINARY);
std::vector<std::vector<cv::Point>> contours;
std::vector<cv::Vec4i> h1;
hg::findContours(threshold_img, contours, h1, CV_CHAIN_APPROX_SIMPLE);
threshold_img.release();
if (contours.size() == 0)
return blockCount;
std::vector<cv::Point2f> list_com;
for (int i = 0; i < contours.size(); i++)
{
double area = cv::contourArea(contours[i]);
if (area > blobAreaSize)
{
blockCount++;
for (int j = 0; j < contours[i].size(); j++)
list_com.push_back(contours[i][j]);
}
}
if (list_com.size() == 0)
return blockCount;
rotatedRect = cv::minAreaRect(list_com);
rotatedRect.center.x /= (float)scale;
rotatedRect.center.y /= (float)scale;
rotatedRect.size.width /= (float)scale;
rotatedRect.size.height /= (float)scale;
if (rotatedRect.angle < -45.0f)
{
rotatedRect.angle += 90.0f;
float l_temp = rotatedRect.size.width;
rotatedRect.size.width = rotatedRect.size.height;
rotatedRect.size.height = l_temp;
}
std::vector<int> hull(list_com.size());
cv::convexHull(list_com, hull);
for (int i = 0; i < hull.size(); i++)
{
cv::Point temp = list_com[hull[i]];
int x = (int)(temp.x / scale);
int y = (int)(temp.y / scale);
maxContour.push_back(cv::Point(x, y));
}
return blockCount;
}
bool CImageApplyDiscardBlank::scalar_LE(const cv::Scalar& val1, const cv::Scalar& val2)
{
for(int i = 0; i < 3; i++)
if(val1[i] > val2[i])
return false;
return true;
}
void CImageApplyDiscardBlank::setIntensity(int val)
{
val = cv::max(cv::min(20, val), 2);
devTh = cv::Scalar(val, val, val, val);
}
cv::Mat CImageApplyDiscardBlank::getRoiMat(const cv::Mat& image)
{
int gap = 100;
cv::RotatedRect rect;
std::vector<cv::Point> contour;
double scale = 0.25;
double thresh = 50;
int blobSize = 200;
int edgeWidth = 10;
processRectR(image, rect, contour, scale, thresh, blobSize);
cv::Rect rect2 = rect.boundingRect();
cv::Rect inRect = rect2 & cv::Rect(0, 0, image.cols, image.rows);
gap = cv::max(inRect.width - rect.size.width, inRect.height - rect.size.height) + 100;
inRect = cv::Rect(inRect.x + gap, inRect.y + gap, inRect.width - gap * 2, inRect.height - gap * 2);
return image(inRect);
}
void CImageApplyDiscardBlank::apply(cv::Mat& pDib,int side)
{
#ifdef LOG
FileTools::write_log("imgprc.txt", "enter CImageApplyDiscardBlank apply");
#endif // LOG
if (pDib.empty())
{
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply");
#endif // LOG
return;
}
setIntensity(isNormalDiscard ? 8 : 20);
setMinArea(isNormalDiscard ? 200 : 300);
cv::Scalar mean;
cv::Scalar dev;
cv::Mat image = getRoiMat(pDib);
cv::Rect rect;
cv::Rect imRect(0, 0, image.cols, image.rows);
for(int i = 0; i < image.cols; i+= dSize)
for(int j = 0; j < image.rows; j+= dSize)
{
rect = cv::Rect(i, j,dSize, dSize) & imRect;
if(rect != cv::Rect())
{
cv::meanStdDev (image(rect) , mean, dev);
if(!scalar_LE(dev, devTh))
{
m_res = false;
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply");
#endif // LOG
return;
}
}
}
m_res = true;
if (m_res)
pDib.release();
#ifdef LOG
FileTools::write_log("imgprc.txt", "exit CImageApplyDiscardBlank apply");
#endif // LOG
}
void CImageApplyDiscardBlank::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
if (mats.empty()) return;
apply(mats[0], 0);
if (isTwoSide && mats.size() > 1)
apply(mats[1], 1);
}