code_device/hgdriver/ImageProcess/ImageApplyTextureRemoval.cpp

188 lines
5.5 KiB
C++
Raw Normal View History

2022-07-29 08:41:34 +00:00
#include "ImageApplyTextureRemoval.h"
//<2F><><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>
void zero_to_center(cv::Mat& image, int colToCut, int rowToCut)
{
cv::Mat q1(image, cv::Rect(0, 0, colToCut, rowToCut));
cv::Mat q2(image, cv::Rect(colToCut, 0, colToCut, rowToCut));
cv::Mat q3(image, cv::Rect(0, rowToCut, colToCut, rowToCut));
cv::Mat q4(image, cv::Rect(colToCut, rowToCut, colToCut, rowToCut));
//<2F>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD>޺͵<DEBA><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD>н<EFBFBD><D0BD><EFBFBD>
cv::Mat tmpImg;
q1.copyTo(tmpImg);
q4.copyTo(q1);
tmpImg.copyTo(q4);
//<2F><>һ<EFBFBD><D2BB><EFBFBD>޺͵<DEBA><CDB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޽<EFBFBD><DEBD>н<EFBFBD><D0BD><EFBFBD>
q2.copyTo(tmpImg);
q3.copyTo(q2);
tmpImg.copyTo(q3);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::Mat create_spectrum(cv::Mat* matArray, double scale = 1.5)
{
cv::Mat dst;
cv::magnitude(matArray[0], matArray[1], dst);
#if 1
cv::divide(dst, dst.cols * dst.rows, dst, scale);
//imshow("Ƶ<><C6B5>", dst);
#else
dst += Scalar::all(1);
log(dst, dst);
normalize(dst, dst, 1, 0, CV_MINMAX);
#endif
#if 0
imshow("Ƶ<EFBFBD><EFBFBD>", dst);
#endif
return dst;
}
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>
void inverseFourierTransform(const cv::Mat& src, cv::Mat& dst)
{
cv::Mat complexIDFT;
cv::Mat matArray[2];
cv::idft(src, complexIDFT);
cv::split(complexIDFT, matArray);
cv::magnitude(matArray[0], matArray[1], dst);
cv::normalize(dst, dst, 0, 1, CV_MINMAX);
}
//<2F><><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2>˲<EFBFBD><CBB2><EFBFBD>
cv::Mat createFilter(const cv::Mat& spectrum, int dilateSize, int erodeSize)
{
cv::Mat temp;
spectrum.convertTo(temp, CV_8UC1, 255);
//cv::imwrite("filter/temp.bmp", temp);
cv::threshold(temp, temp, 0, 255, CV_THRESH_OTSU);
//cv::imwrite("filter/temp1.bmp", temp);
cv::Mat element1 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(dilateSize, dilateSize));
cv::Mat element2 = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(erodeSize, erodeSize));
cv::line(temp, cv::Point(0, temp.rows / 2), cv::Point(temp.cols - 1, temp.rows / 2), cv::Scalar(255));
cv::line(temp, cv::Point(temp.cols / 2, 0), cv::Point(temp.cols / 2, temp.rows - 1), cv::Scalar(255));
cv::dilate(temp, temp, element1);
cv::erode(temp, temp, element2);
//cv::imwrite("filter/temp2.bmp", temp);
cv::floodFill(temp, cv::Point(temp.cols / 2, temp.rows / 2), cv::Scalar(0)); //<2F><>ˮ<EFBFBD><CBAE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::blur(~temp, temp, cv::Size(3, 3)); //<2F><>ֵ<EFBFBD>˲<EFBFBD>
//cv::imwrite("filter/temp3.bmp", temp);
//temp = ~temp;
//<2F>ݲ<EFBFBD><DDB2>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cv::Mat filter;
temp.convertTo(filter, CV_32FC1);
cv::normalize(filter, filter, 1, 0.01, CV_MINMAX);
std::vector<cv::Mat> mv;
mv.push_back(filter);
mv.push_back(filter);
cv::merge(mv, filter);
return filter;
}
void CImageApplyTextureRemoval::textureRemovalGray(cv::Mat& img)
{
//<2F>õ<EFBFBD>DFT<46><54><EFBFBD><EFBFBD><EFBFBD>ѳߴ磨2<E7A3A8><32>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC>ټ<EFBFBD><D9BC><EFBFBD>
cv::Mat resizeMat;
cv::resize(img, resizeMat, cv::Size(), 0.5, 0.5);
cv::Mat paddedImg;
int m = cv::getOptimalDFTSize(resizeMat.rows);
int n = cv::getOptimalDFTSize(resizeMat.cols);
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>¶˺<C2B6><CBBA>Ҷ<EFBFBD>
cv::copyMakeBorder(resizeMat, paddedImg, 0, m - resizeMat.rows, 0, n - resizeMat.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><E9A3A8><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD>Mat<61><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>DFT
cv::Mat matArray[] = { cv::Mat_<float>(paddedImg), cv::Mat::zeros(paddedImg.size(), CV_32F) };
cv::Mat complexInput, complexOutput;
cv::merge(matArray, 2, complexInput);
cv::dft(complexInput, complexOutput);
cv::split(complexOutput, matArray); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ף<EFBFBD><D7A3><EFBFBD><EFBFBD><EFBFBD>Ҷ<EFBFBD>ף<EFBFBD>
//<2F>˲<EFBFBD>
//<2F><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><EFBFBD>鲿<EFBFBD><E9B2BF><EFBFBD><EFBFBD>Ƶ<EFBFBD><C6B5>ͼ<EFBFBD>ķ<EFBFBD>ʽ<EFBFBD><CABD>λ
//<2F><>Ƶ<EFBFBD><C6B5>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD>
zero_to_center(matArray[0], complexOutput.cols / 2, complexOutput.rows / 2);
zero_to_center(matArray[1], complexOutput.cols / 2, complexOutput.rows / 2);
cv::Mat spectrum = create_spectrum(matArray);
//<2F><><EFBFBD><EFBFBD><EFBFBD>˲<EFBFBD><CBB2><EFBFBD>
cv::Mat filter = createFilter(spectrum, m_dilateSize, m_erodeSize);
cv::merge(matArray, 2, complexOutput);
cv::multiply(complexOutput, filter, filter);
cv::Size imgSize = img.size();
m = cv::getOptimalDFTSize(img.rows);
n = cv::getOptimalDFTSize(img.cols);
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>¶˺<C2B6><CBBA>Ҷ<EFBFBD>
cv::copyMakeBorder(img, img, 0, m - img.rows, 0, n - img.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
cv::copyMakeBorder(filter, filter, 0, m - filter.rows, 0, n - filter.cols,
cv::BORDER_CONSTANT, cv::Scalar::all(0));
//IDFT<46>õ<EFBFBD><C3B5>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>
inverseFourierTransform(filter, img);
img = img(cv::Rect(cv::Point(0, 0), imgSize));
img *= 255;
img.convertTo(img, CV_8UC1);
}
CImageApplyTextureRemoval::CImageApplyTextureRemoval()
: CImageApply()
, m_dilateSize(9)
, m_erodeSize(5)
{
}
CImageApplyTextureRemoval::CImageApplyTextureRemoval(int dilateSize, int erodeSize)
: CImageApply()
, m_dilateSize(dilateSize)
, m_erodeSize(erodeSize)
{
}
CImageApplyTextureRemoval::~CImageApplyTextureRemoval()
{
}
void CImageApplyTextureRemoval::apply(cv::Mat& pDib, int side)
{
(void)side;
if (pDib.channels() == 1)
textureRemovalGray(pDib);
else
{
std::vector<cv::Mat> rgb(3);
cv::split(pDib, rgb);
for (cv::Mat& var : rgb)
textureRemovalGray(var);
cv::merge(rgb, pDib);
}
}
void CImageApplyTextureRemoval::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
{
(void)isTwoSide;
int i = 0;
for (cv::Mat& var : mats) {
if (i != 0 && isTwoSide == false)
break;
if (!var.empty())
apply(var, 0);
i++;
}
}