Zad9 #9
@ -55,69 +55,78 @@ PNM* Convolution::convolute(math::matrix<float> mask, Mode mode = CyclicEdge)
|
||||
float blue_sum;
|
||||
float gray_sum;
|
||||
|
||||
|
||||
|
||||
for (int x=0; x<width; x++)
|
||||
for (int y=0; y<height; y++)
|
||||
{
|
||||
|
||||
|
||||
if (image->format() == QImage::Format_Indexed8)
|
||||
gray_window=getWindow(x,y,size,LChannel,mode);
|
||||
else{
|
||||
red_window=getWindow(x,y,size,RChannel,mode);
|
||||
blue_window=getWindow(x,y,size,BChannel,mode);
|
||||
green_window=getWindow(x,y,size,GChannel,mode);
|
||||
//gray_window=getWindow(x,y,size,LChannel,mode);
|
||||
|
||||
}
|
||||
|
||||
if (image->format() == QImage::Format_Indexed8){
|
||||
gray_window=join(gray_window,mask);
|
||||
}else{
|
||||
red_window=join(red_window,mask);
|
||||
blue_window=join(blue_window,mask);
|
||||
green_window=join(green_window,mask);
|
||||
|
||||
//gray_window=join(gray_window,mask);
|
||||
|
||||
red_sum=sum(red_window);
|
||||
green_sum=sum(green_window);
|
||||
blue_sum=sum(blue_window);
|
||||
//gray_sum=sum(gray_window);
|
||||
}
|
||||
|
||||
|
||||
if(mask_weight>0)
|
||||
{
|
||||
red_sum=red_sum/mask_weight;
|
||||
blue_sum=blue_sum/mask_weight;
|
||||
green_sum=green_sum/mask_weight;
|
||||
//gray_sum=gray_sum/mask_weight;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if(red_sum>=0 && red_sum<=255 && green_sum>=0 && green_sum<=255 && blue_sum>=0 && blue_sum<=255)
|
||||
{
|
||||
newImage->setPixel(x,y, QColor(red_sum,green_sum,blue_sum).rgb());
|
||||
}
|
||||
else if (red_sum>=0 && red_sum<=255 && green_sum>=0 && green_sum<=255)
|
||||
{
|
||||
int old_blue = qBlue(newImage->pixel(x,y));
|
||||
newImage->setPixel(x,y, QColor(red_sum,green_sum,old_blue).rgb());
|
||||
}
|
||||
else if (blue_sum>=0 && blue_sum<=255 && green_sum>=0 && green_sum<=255)
|
||||
{
|
||||
int old_red = qRed(newImage->pixel(x,y));
|
||||
newImage->setPixel(x,y, QColor(old_red,green_sum,blue_sum).rgb());
|
||||
}
|
||||
else if (blue_sum>=0 && blue_sum<=255 && red_sum>=0 && red_sum<=255)
|
||||
{
|
||||
int old_green = qGreen(newImage->pixel(x,y));
|
||||
newImage->setPixel(x,y, QColor(red_sum,old_green,blue_sum).rgb());
|
||||
}
|
||||
|
||||
if (image->format() == QImage::Format_Indexed8){
|
||||
gray_sum=sum(gray_window);
|
||||
}else{
|
||||
red_sum=sum(red_window);
|
||||
green_sum=sum(green_window);
|
||||
blue_sum=sum(blue_window);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(mask_weight>0)
|
||||
{
|
||||
|
||||
if (image->format() == QImage::Format_Indexed8){
|
||||
gray_sum=gray_sum/mask_weight;
|
||||
}
|
||||
else{
|
||||
red_sum=red_sum/mask_weight;
|
||||
blue_sum=blue_sum/mask_weight;
|
||||
green_sum=green_sum/mask_weight;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (image->format() == QImage::Format_Indexed8) {
|
||||
newImage->setPixel(x, y, validateValue(gray_sum));
|
||||
}
|
||||
else {
|
||||
newImage->setPixel(x,y, QColor(validateValue(red_sum),validateValue(green_sum),validateValue(blue_sum)).rgb());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return newImage;
|
||||
}
|
||||
|
||||
int Convolution::validateValue(int value){
|
||||
|
||||
if (value > 255) {
|
||||
return 255;
|
||||
}
|
||||
else if (value < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/** Joins to matrices by multiplying the A[i,j] with B[i,j].
|
||||
* Warning! Both Matrices must be squares with the same size!
|
||||
*/
|
||||
@ -141,18 +150,15 @@ const float Convolution::sum(const math::matrix<float> A)
|
||||
{
|
||||
float sum = 0.0;
|
||||
|
||||
int size=A.rowno();
|
||||
|
||||
for (int x=0; x<size; x++)
|
||||
for (int y=0; y<size; y++)
|
||||
|
||||
for (int x=0; x<A.rowno(); x++)
|
||||
for (int y=0; y<A.colno(); y++)
|
||||
{
|
||||
sum=sum+A[x][y];
|
||||
}
|
||||
|
||||
|
||||
|
||||
return sum;
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -165,16 +171,14 @@ const math::matrix<float> Convolution::reflection(const math::matrix<float> A)
|
||||
int counter_j=0;
|
||||
|
||||
|
||||
for (int x=size-1; x>=0; x--)
|
||||
{
|
||||
for (int y=size-1; y>=0; y--)
|
||||
{
|
||||
C[x][y]=A[counter_i][counter_j];
|
||||
counter_j++;
|
||||
}
|
||||
counter_i++;
|
||||
}
|
||||
for (int x = 0; x < size; x++)
|
||||
{
|
||||
for (int y = 0; y < size; y++)
|
||||
{
|
||||
C(size - x, size - y) = A(x, y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return C;
|
||||
}
|
||||
}
|
||||
|
@ -18,6 +18,7 @@ protected:
|
||||
const math::matrix<float> join(math::matrix<float>, math::matrix<float>);
|
||||
const float sum(math::matrix<float>);
|
||||
const math::matrix<float> reflection(math::matrix<float>);
|
||||
int validateValue(int);
|
||||
};
|
||||
|
||||
#endif // CONVOLUTION_H
|
||||
|
@ -23,8 +23,192 @@ PNM* EdgeCanny::transform()
|
||||
lower_thresh = getParameter("lower_threshold").toInt();
|
||||
|
||||
PNM* newImage = new PNM(width, height, QImage::Format_Grayscale8);
|
||||
QPoint point_vector[7] = {
|
||||
QPoint(-1, 0),
|
||||
QPoint(-1, 1),
|
||||
QPoint(0, -1),
|
||||
QPoint(0, 1),
|
||||
QPoint(1, -1),
|
||||
QPoint(1, 0),
|
||||
QPoint(1, 1),
|
||||
};
|
||||
|
||||
qDebug() << Q_FUNC_INFO << "Not implemented yet!";
|
||||
// step 1
|
||||
PNM* tmpImage = new PNM(width, height, QImage::Format_Indexed8);
|
||||
tmpImage = ConversionGrayscale(image).transform();
|
||||
// step 2
|
||||
BlurGaussian gaus(tmpImage);
|
||||
gaus.setParameter("sigma", 1.6);
|
||||
gaus.setParameter("size", 3);
|
||||
tmpImage = gaus.transform();
|
||||
|
||||
// step 3
|
||||
EdgeSobel sobel(tmpImage);
|
||||
math::matrix<float>* Gx = sobel.rawHorizontalDetection();
|
||||
math::matrix<float>* Gy = sobel.rawVerticalDetection();
|
||||
//step 4
|
||||
math::matrix<float> direction = math::matrix<float>(width, height);
|
||||
math::matrix<float> power = math::matrix<float>(width, height);
|
||||
for (int i = 0; i < width; i++)
|
||||
{
|
||||
for (int j = 0; j < height; j++)
|
||||
{
|
||||
newImage->setPixel(i, j, PIXEL_VAL_MIN);
|
||||
power(i, j) = sqrt(pow((*Gx)(i, j), 2) + pow((*Gy)(i, j), 2));
|
||||
direction(i, j) = (int)((atan2 ((*Gy)(i, j), (*Gx)(i, j)) / (3.142)) * 180 + 360) % 360;
|
||||
}
|
||||
}
|
||||
|
||||
//step 5
|
||||
std::list<QPoint> initialPoints;
|
||||
for (int i = 1; i < width - 1; i++)
|
||||
{
|
||||
for (int j = 1; j < height - 1; j++)
|
||||
{
|
||||
|
||||
int pos = direction(i, j);
|
||||
|
||||
QPoint point1;
|
||||
QPoint point2;
|
||||
|
||||
if (getOrient(pos) == 0)
|
||||
{
|
||||
point1 = QPoint(0, -1);
|
||||
point2 = QPoint(0, 1);
|
||||
}
|
||||
else if (getOrient(pos) == 1)
|
||||
{
|
||||
point1 = QPoint(1, -1);
|
||||
point2 = QPoint(-1, 1);
|
||||
}
|
||||
else if (getOrient(pos) == 2)
|
||||
{
|
||||
point1 = QPoint(-1, 0);
|
||||
point2 = QPoint(1, 0);
|
||||
}
|
||||
else if (getOrient(pos) == 3)
|
||||
{
|
||||
point1 = QPoint(-1, -1);
|
||||
point2 = QPoint(1, 1);
|
||||
}
|
||||
|
||||
double temp1 = power(i + point1.x(), j + point1.y());
|
||||
double temp2= power(i + point2.x(), j + point2.y());
|
||||
|
||||
if (power(i, j) > temp1 && power(i, j) > temp2 &&power(i, j) > upper_thresh)
|
||||
{
|
||||
newImage->setPixel(i, j, PIXEL_VAL_MAX);
|
||||
initialPoints.push_back(QPoint(i, j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//step 6
|
||||
while (!initialPoints.empty())
|
||||
{
|
||||
QPoint point = initialPoints.back();
|
||||
initialPoints.pop_back();
|
||||
int pos = direction(point.x(), point.y());
|
||||
|
||||
for (int i = 1; i <= 2; i++)
|
||||
{
|
||||
int x,y;
|
||||
|
||||
if ( i == 1)
|
||||
{
|
||||
if (getOrient(pos) == 0)
|
||||
{
|
||||
x= 0;
|
||||
y= -1;
|
||||
|
||||
}
|
||||
else if (getOrient(pos) == 1)
|
||||
{
|
||||
x= 1;
|
||||
y= -1;
|
||||
}
|
||||
else if (getOrient(pos) == 2)
|
||||
{
|
||||
x= -1;
|
||||
y= 1;
|
||||
}
|
||||
else if (getOrient(pos) == 3)
|
||||
{
|
||||
x= -1;
|
||||
y= -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getOrient(pos) == 0)
|
||||
{
|
||||
x= 0;
|
||||
y= 1;
|
||||
}
|
||||
else if (getOrient(pos) == 1)
|
||||
{
|
||||
x= -1;
|
||||
y= 1;
|
||||
}
|
||||
else if (getOrient(pos) == 2)
|
||||
{
|
||||
x= 1;
|
||||
y= 0;
|
||||
}
|
||||
else if (getOrient(pos) == 3)
|
||||
{
|
||||
x= 1;
|
||||
y= 1;
|
||||
}
|
||||
}
|
||||
QPoint cPoint = point;
|
||||
while (true)
|
||||
{
|
||||
QPoint point_ = QPoint(cPoint.x() + x, cPoint.y() + y);
|
||||
if (point_.x() == width - 1 || point_.x() == 0 || point_.y() == height - 1 || point_.y() == 0) break;
|
||||
if (newImage->pixel(point_.x(), point_.y()) == PIXEL_VAL_MAX) break;
|
||||
if (power(point_.x(), point_.y()) < lower_thresh) break;
|
||||
if (getOrient((int)direction(point_.x(), point_.y())) != getOrient(pos)) break;
|
||||
bool flag = true;
|
||||
|
||||
for (int i = 0; i < 7; i++)
|
||||
{
|
||||
QPoint point(point_.x() + point_vector[i].x(), point_.y() + point_vector[i].y());
|
||||
if (point.x() == cPoint.x() && point.y() == cPoint.y()) continue;
|
||||
if (getOrient((int)direction(point.x(), point.y())) != getOrient(pos)) continue;
|
||||
|
||||
if (power(point.x(), point.y()) >= power(point_.x(), point_.y()))
|
||||
{
|
||||
flag= false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) break;
|
||||
newImage->setPixel(point_.x(), point_.y(), PIXEL_VAL_MAX);
|
||||
cPoint = point_;
|
||||
}
|
||||
}
|
||||
}
|
||||
return newImage;
|
||||
}
|
||||
|
||||
|
||||
int EdgeCanny::getOrient(int currentDirection){
|
||||
if ((currentDirection >= 0 && currentDirection < 23) || (currentDirection >= 158 && currentDirection < 203) || (currentDirection >= 338 && currentDirection < 361))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ((currentDirection >= 23 && currentDirection < 68) || (currentDirection >= 203 && currentDirection < 248))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if ((currentDirection >= 68 && currentDirection < 113) || (currentDirection >= 248 && currentDirection < 293))
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
if ((currentDirection >= 113 && currentDirection < 158) || (currentDirection >= 293 && currentDirection < 338))
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -8,12 +8,14 @@ class EdgeCanny : public Convolution
|
||||
public:
|
||||
EdgeCanny(PNM*);
|
||||
EdgeCanny(PNM*, ImageViewer*);
|
||||
int getOrient(int);
|
||||
|
||||
virtual PNM* transform();
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // EDGECANNY_H
|
||||
|
@ -46,15 +46,15 @@ math::matrix<float>* EdgeSobel::rawHorizontalDetection()
|
||||
|
||||
int width = x_gradient->rowno();
|
||||
int height = x_gradient->colno();
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
for (int y = 0; y < height; y++)
|
||||
{
|
||||
math::matrix<float> temp = getWindow(x, y, 3, LChannel, NullEdge);
|
||||
x_gradient[x][y] = Convolution::sum(Convolution::join(g_x, temp));
|
||||
}
|
||||
math::matrix<float> temp = getWindow(x, y, 3, LChannel, NullEdge);
|
||||
x_gradient[x][y] = Convolution::sum(Convolution::join(g_x, temp));
|
||||
|
||||
}
|
||||
}
|
||||
return x_gradient;
|
||||
}
|
||||
|
||||
@ -62,6 +62,7 @@ math::matrix<float>* EdgeSobel::rawVerticalDetection()
|
||||
{
|
||||
math::matrix<float>* y_gradient = new math::matrix<float>(this->image->width(), this->image->height());
|
||||
|
||||
|
||||
int width = y_gradient->rowno();
|
||||
int height = y_gradient->colno();
|
||||
|
||||
@ -74,5 +75,6 @@ math::matrix<float>* EdgeSobel::rawVerticalDetection()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return y_gradient;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user