173 lines
4.6 KiB
C++
173 lines
4.6 KiB
C++
|
#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::threshold(temp, temp, 0, 255, CV_THRESH_OTSU);
|
|||
|
//imshow("<22><>ֵ<EFBFBD><D6B5>", 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::dilate(temp, temp, element1);
|
|||
|
cv::erode(temp, temp, element2);
|
|||
|
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::medianBlur(~temp, temp, 3); //<2F><>ֵ<EFBFBD>˲<EFBFBD>
|
|||
|
//temp = ~temp;
|
|||
|
//cv::imshow("<22><>ֵ<EFBFBD><D6B5>", 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 paddedImg;
|
|||
|
int m = cv::getOptimalDFTSize(img.rows);
|
|||
|
int n = cv::getOptimalDFTSize(img.cols);
|
|||
|
|
|||
|
//<2F><><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC><EFBFBD><EFBFBD><EFBFBD>¶˺<C2B6><CBBA>Ҷ<EFBFBD>
|
|||
|
cv::copyMakeBorder(img, paddedImg, 0, m - img.rows, 0, n - img.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);
|
|||
|
|
|||
|
//IDFT<46>õ<EFBFBD><C3B5>˲<EFBFBD><CBB2><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
cv::Size imgSize = img.size();
|
|||
|
inverseFourierTransform(filter, img);
|
|||
|
img = img(cv::Rect(cv::Point(0, 0), imgSize));
|
|||
|
img *= 255;
|
|||
|
img.convertTo(img, CV_8UC1);
|
|||
|
}
|
|||
|
|
|||
|
CImageApplyTextureRemoval::CImageApplyTextureRemoval()
|
|||
|
: CImageApply()
|
|||
|
, m_dilateSize(5)
|
|||
|
, m_erodeSize(3)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
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);
|
|||
|
}
|
|||
|
|
|||
|
pDib *= 1.15;
|
|||
|
}
|
|||
|
|
|||
|
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++;
|
|||
|
}
|
|||
|
}
|