アルファチャンネルが単色の場合、cv::INTER_NEARESTで拡大するようにした

This commit is contained in:
lltcggie 2016-10-14 16:47:44 +09:00
parent 522785ce33
commit 8c85eb2358
2 changed files with 69 additions and 3 deletions

View File

@ -350,6 +350,7 @@ void stImage::Clear()
mOrgFloatImage.release(); mOrgFloatImage.release();
mTmpImageRGB.release(); mTmpImageRGB.release();
mTmpImageA.release(); mTmpImageA.release();
mTmpImageAOneColor.release();
mEndImage.release(); mEndImage.release();
} }
@ -425,6 +426,34 @@ void stImage::Preprocess(const int input_plane, const int net_offset)
ConvertToNetFormat(input_plane, net_offset); ConvertToNetFormat(input_plane, net_offset);
} }
bool stImage::IsOneColor(const cv::Mat & im)
{
assert(im.channels() == 1);
const size_t Line = im.step1();
const size_t Width = im.size().width;
const size_t Height = im.size().height;
if (Width == 0 && Height == 0)
return true;
const float *ptr = (const float *)im.data;
const float color = ptr[0];
for (size_t i = 0; i < Height; i++)
{
for (size_t j = 0; j < Width; j++)
{
const size_t pos = Line * i + j;
if (ptr[pos] != color)
return false;
}
}
return true;
}
void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset) void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset)
{ {
if (input_plane == 1) // Yモデル if (input_plane == 1) // Yモデル
@ -470,10 +499,18 @@ void stImage::ConvertToNetFormat(const int input_plane, const int alpha_offset)
mTmpImageA = planes[3]; mTmpImageA = planes[3];
planes.resize(3); planes.resize(3);
AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる if (!IsOneColor(mTmpImageA))
{
AlphaMakeBorder(planes, mTmpImageA, alpha_offset); // 透明なピクセルと不透明なピクセルの境界部分の色を広げる
// α拡大用にRGBに変換 // α拡大用にRGBに変換
cv::cvtColor(mTmpImageA, mTmpImageA, CV_GRAY2RGB); cv::cvtColor(mTmpImageA, mTmpImageA, CV_GRAY2RGB);
}
else
{
mTmpImageAOneColor = mTmpImageA;
mTmpImageA.release();
}
} }
// BGRからRGBにする // BGRからRGBにする
@ -630,6 +667,21 @@ void stImage::DeconvertFromNetFormat(const int input_plane)
planes.push_back(mTmpImageA); planes.push_back(mTmpImageA);
mTmpImageA.release(); mTmpImageA.release();
cv::merge(planes, mEndImage);
}
else if (!mTmpImageAOneColor.empty()) // 単色版Aを戻す
{
std::vector<cv::Mat> planes;
cv::split(mEndImage, planes);
cv::Size_<int> zoom_size = planes[0].size();
// マージ先のサイズに合わせる
cv::resize(mTmpImageAOneColor, mTmpImageAOneColor, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
planes.push_back(mTmpImageAOneColor);
mTmpImageAOneColor.release();
cv::merge(planes, mEndImage); cv::merge(planes, mEndImage);
} }
} }
@ -657,6 +709,16 @@ void stImage::DeconvertFromNetFormat(const int input_plane)
planes.push_back(mTmpImageA); planes.push_back(mTmpImageA);
mTmpImageA.release(); mTmpImageA.release();
} }
else if (!mTmpImageAOneColor.empty()) // 単色版Aを戻す
{
cv::Size_<int> zoom_size = planes[0].size();
// マージ先のサイズに合わせる
cv::resize(mTmpImageAOneColor, mTmpImageAOneColor, zoom_size, 0.0, 0.0, cv::INTER_NEAREST);
planes.push_back(mTmpImageAOneColor);
mTmpImageAOneColor.release();
}
// RGBからBGRにする // RGBからBGRにする
std::swap(planes[0], planes[2]); std::swap(planes[0], planes[2]);

View File

@ -14,6 +14,7 @@ private:
cv::Mat mTmpImageRGB; // RGB(あるいはY) cv::Mat mTmpImageRGB; // RGB(あるいはY)
cv::Mat mTmpImageA; // αチャンネル cv::Mat mTmpImageA; // αチャンネル
cv::Mat mTmpImageAOneColor; // αチャンネル(単色の場合使われる)
cv::Mat mEndImage; // 完成した画像 cv::Mat mEndImage; // 完成した画像
@ -47,6 +48,9 @@ private:
static Waifu2x::eWaifu2xError WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional<int> &output_quality); static Waifu2x::eWaifu2xError WriteMat(const cv::Mat &im, const boost::filesystem::path &output_file, const boost::optional<int> &output_quality);
// im(1ch)が単色で構成されているか判定
static bool IsOneColor(const cv::Mat &im);
void ConvertToNetFormat(const int input_plane, const int alpha_offset); void ConvertToNetFormat(const int input_plane, const int alpha_offset);
Waifu2x::eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im); Waifu2x::eWaifu2xError CreateBrightnessImage(const cv::Mat &float_image, cv::Mat &im);