113 lines
2.8 KiB
C++
113 lines
2.8 KiB
C++
|
#include "noise_median.h"
|
||
|
|
||
|
NoiseMedian::NoiseMedian(PNM* img) :
|
||
|
Convolution(img)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
NoiseMedian::NoiseMedian(PNM* img, ImageViewer* iv) :
|
||
|
Convolution(img, iv)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
PNM* NoiseMedian::transform()
|
||
|
{
|
||
|
int width = image->width();
|
||
|
int height = image->height();
|
||
|
|
||
|
PNM* newImage = new PNM(width, height, image->format());
|
||
|
|
||
|
|
||
|
for (int i = 0; i < width; i++)
|
||
|
{
|
||
|
for (int j = 0; j < height; j++)
|
||
|
{
|
||
|
if (image->format() == QImage::Format_Indexed8)
|
||
|
{
|
||
|
// Get median value for LChannel and set as new pixel
|
||
|
newImage->setPixel(i, j, getMedian(i, j, LChannel));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Get median values for RGB channels
|
||
|
int r_med = getMedian(i, j, RChannel);
|
||
|
int g_med = getMedian(i, j, GChannel);
|
||
|
int b_med = getMedian(i, j, BChannel);
|
||
|
|
||
|
// Create new color
|
||
|
QColor color = QColor(r_med, g_med, b_med);
|
||
|
|
||
|
// Set new pixel with rgb color
|
||
|
newImage->setPixel(i, j, color.rgb());
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return newImage;
|
||
|
}
|
||
|
|
||
|
int NoiseMedian::getMedian(int x, int y, Channel channel)
|
||
|
{
|
||
|
int radius = getParameter("radius").toInt();
|
||
|
int window_size = 2 * radius + 1;
|
||
|
|
||
|
math::matrix<int> window = getWindow(x, y, window_size, channel, RepeatEdge);
|
||
|
std::vector<int> result; //list does not provide a subscript operator
|
||
|
|
||
|
for(std::size_t i=0; i < window.rowno(); i++){
|
||
|
for(std::size_t j=0; j < window.colno(); j++){
|
||
|
result.push_back(window[i][j]);
|
||
|
}
|
||
|
}
|
||
|
std::sort(result.begin(), result.end());
|
||
|
int middle = result.size()/2;
|
||
|
return result[middle];
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
// Different solution
|
||
|
int NoiseMedian::getMedian(int x, int y, Channel channel)
|
||
|
{
|
||
|
int radius = getParameter("radius").toInt();
|
||
|
int window_size = 2 * radius + 1;
|
||
|
|
||
|
int powSize = size*size;
|
||
|
int window[powSize];
|
||
|
|
||
|
int sr = 0;
|
||
|
int sc = 0;
|
||
|
int lp = 0;
|
||
|
float value;
|
||
|
|
||
|
for (sr = x-radius; sr <= x+radius; sr++)
|
||
|
{
|
||
|
for (sc = y-radius; sc <= y+radius; sc++)
|
||
|
{
|
||
|
QRgb color = getPixel(sr, sc, CyclicEdge);
|
||
|
|
||
|
switch(channel)
|
||
|
{
|
||
|
case LChannel:
|
||
|
value = qGray (color);
|
||
|
break;
|
||
|
case RChannel:
|
||
|
value = qRed (color);
|
||
|
break;
|
||
|
case GChannel:
|
||
|
value = qGreen(color);
|
||
|
break;
|
||
|
case BChannel:
|
||
|
value = qBlue (color);
|
||
|
break;
|
||
|
}
|
||
|
window[lp++] = value;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
std::sort(window, window + powSize);
|
||
|
int center = powSize / 2;
|
||
|
int result = window[center];
|
||
|
return result;
|
||
|
}
|
||
|
*/
|