📄 filter.cpp
字号:
/*
This "SOFTWARE" is a free software.
You are allowed to download, use, modify and redistribute this software.
The software is provided "AS IS" without warranty of any kind.
Copyright: University of Koblenz-Landau, Dirk Balthasar
*/
#include <ToolsReport.h>
#include <advconsole.h>
#include <ToolsImageFilter.h>
#include <Matrix.h>
#include <COLORREF2.h>
#include <ToolsFiles.h>
#include <ToolsImage.h>
int main(int argc, char* argv[])
{
advConsoleParameters parser("Filter");
parser.addObligatoryParameter("FilterName", "ku = Kuwahara-Nagao, snn = symmetric nearest neighbour, sp = salt and pepper noise");
parser.addObligatoryParameter("InputPPM", "Name of inputfile");
parser.addObligatoryParameter("OutputPPM", "Name of Outputfile");
parser.addOptionProperty("cs", "ColorSpace", "rgb1", "Only supported with filter -ku\n rgb1: Replace center-pixel by the the mean color of sector with lowest variance in rgb colorspace\n rgb2: Replace center-pixel by the pixel with lowest distance to mean color of sector with lowest varinace\n rgb3: Replace center-pixel by the pixel with lowest distance to mean color of sector with lowest variance, only if center-pixel has highest distance to mean color\n hsv: Replace pixel by mean color of sector with lowest variance, calculated in hsv colorspace\n");
parser.addOptionProperty("it", "Iterations", "1", "The filter will be applied it times. Default 1");
parser.addOptionProperty("n", "noise", "10", "Percentage of salt and pepper noise [0..100] (only for filter -sp)");
int pres = parser.parseCommandLine(argc-1, (const char**)&argv[1]);
std::string Filter = parser.getObligatoryParameter("FilterName"),
InputPPM = parser.getObligatoryParameter("InputPPM"),
OutputPPM = parser.getObligatoryParameter("OutputPPM"),
ColorSpace = parser.getOptionProperty("ColorSpace");
int iterations = atoi(parser.getOptionProperty("Iterations").c_str());
CMatrix<COLORREF2> InputImage, OutputImage, InputImageBak;
if (tools::LoadPPM<CMatrix<COLORREF2>, COLORREF2, tools::CCOLORREF2access>(InputPPM.c_str(), InputImage))
{
OutputImage.SetSize(InputImage.GetWidth(), InputImage.GetHeight());
InputImageBak = InputImage;
CMatrix<COLORREF2> *In = NULL,
*Out = NULL;
tools::LogMessageFmt("Filter %s",Filter.c_str());
int it = iterations,
LastMin = -1,
LastMinDidNotChange = 0,
ChangedPixels = 1;
while (iterations > 0 && ChangedPixels > 0 && LastMinDidNotChange < 10)
{
tools::LogMessageFmt("Filter iteration: %d",it-iterations+1);
iterations--;
if (In == NULL)
{
In = &InputImage;
Out = &OutputImage;
}else
{ // swap in/out
CMatrix<COLORREF2> *tmp;
tmp = In;
In = Out;
Out = tmp;
}
if (strcmp(Filter.c_str(), "ku") == 0)
{ // Kuwahara-Nagao
if (strcmp(ColorSpace.c_str(), "rgb1") == 0)
{
tools::FilterKuwaharaNagaoReplacePixelMeanRGB<CMatrix<COLORREF2>, tools::CCOLORREF2access> prrgb;
tools::FilterKuwaharaNagaoGeneric<CMatrix<COLORREF2>, tools::CCOLORREF2access, tools::FilterKuwaharaNagaoReplacePixelMeanRGB<CMatrix<COLORREF2>, tools::CCOLORREF2access> >(*In, *Out, prrgb);
//tools::FilterKuwaharaNagaoMeanRGB<CMatrix<COLORREF2>, tools::CCOLORREF2access>(*In, *Out);
}
else
if (strcmp(ColorSpace.c_str(), "hsv") == 0)
{
tools::FilterKuwaharaNagaoReplacePixelMeanHSV<CMatrix<COLORREF2>, tools::CCOLORREF2access> prhsv;
tools::FilterKuwaharaNagaoGeneric<CMatrix<COLORREF2>, tools::CCOLORREF2access, tools::FilterKuwaharaNagaoReplacePixelMeanHSV<CMatrix<COLORREF2>, tools::CCOLORREF2access> >(*In, *Out, prhsv);
//tools::FilterKuwaharaNagaoMeanHSV<CMatrix<COLORREF2>, tools::CCOLORREF2access>(*In, *Out);
}
else
if (strcmp(ColorSpace.c_str(), "rgb2") == 0)
{
tools::FilterKuwaharaNagaoReplacePixelMeanMinDist<CMatrix<COLORREF2>, tools::CCOLORREF2access> prrgb2;
tools::FilterKuwaharaNagaoGeneric<CMatrix<COLORREF2>, tools::CCOLORREF2access, tools::FilterKuwaharaNagaoReplacePixelMeanMinDist<CMatrix<COLORREF2>, tools::CCOLORREF2access> >(*In, *Out, prrgb2);
//tools::FilterKuwaharaNagaoMeanHSV<CMatrix<COLORREF2>, tools::CCOLORREF2access>(*In, *Out);
}
else
if (strcmp(ColorSpace.c_str(), "rgb3") == 0)
{
tools::FilterKuwaharaNagaoReplaceMeanMinIfMax<CMatrix<COLORREF2>, tools::CCOLORREF2access> prrgb3;
tools::FilterKuwaharaNagaoGeneric<CMatrix<COLORREF2>, tools::CCOLORREF2access, tools::FilterKuwaharaNagaoReplaceMeanMinIfMax<CMatrix<COLORREF2>, tools::CCOLORREF2access> >(*In, *Out, prrgb3);
//tools::FilterKuwaharaNagaoMeanHSV<CMatrix<COLORREF2>, tools::CCOLORREF2access>(*In, *Out);
}
}else
if (strcmp(Filter.c_str(), "snn") == 0)
{ // snn
tools::FilterSNN<CMatrix<COLORREF2>, tools::CCOLORREF2access>(*In, *Out);
}
else
if (strcmp(Filter.c_str(), "sp") == 0)
{ // salt & pepper
float SP_percent =(float)atoi(parser.getOptionProperty("noise").c_str()) / 100;
tools::LogMessageFmt("Adding %3.0f%% noise",SP_percent*100.0);
for (int x = 0; x < In->GetWidth(); x++)
{
for (int y = 0; y < In->GetHeight(); y++)
{
if (tools::Rand() < SP_percent)
{
if (tools::Rand() < 0.5)
(*Out)(x,y) = tools::CCOLORREF2access::PackRGB(255,255,255);
else
(*Out)(x,y) = tools::CCOLORREF2access::PackRGB(0,0,0);
}else
{
(*Out)(x,y) = (*In)(x,y);
}
}
}
}else
{
tools::LogMessageFmt("Filter %s unknown.",Filter.c_str());
}
ChangedPixels = tools::DifferntPixelCount(*In, *Out, tools::CROI(0,0,In->GetWidth()-1,In->GetHeight()-1));
if (LastMin == -1 || ChangedPixels < LastMin)
{
LastMin=ChangedPixels;
LastMinDidNotChange = 0;
}
else
LastMinDidNotChange++;
tools::LogMessageFmt("Changed pixels %d (%f%%)",ChangedPixels, (float)ChangedPixels / (float)(In->GetHeight()*In->GetWidth())*100.0f);
}
tools::SavePPM<CMatrix<COLORREF2>, COLORREF2, tools::CCOLORREF2access>(OutputPPM.c_str(), *Out);
ChangedPixels = tools::DifferntPixelCount(InputImageBak, *Out, tools::CROI(0,0,In->GetWidth()-1,In->GetHeight()-1));
tools::LogMessageFmt("Changed Pixels total: %d (%f%%)",ChangedPixels, (float)ChangedPixels / (float)(In->GetHeight()*In->GetWidth())*100.0f);
}else
{
tools::LogMessageFmt("%s",parser.GetHelp().c_str());
tools::LogMessageFmt("Error: File %s not found or wrong file format.", InputPPM.c_str());
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -