cofactor
asked on
can anybody explain copy constructor
hi, i want to understand the copy constructor. how it works. i could not understand bcoz there are weired syntaxes in my book. i think copy constructor is a very imporatant feature of C++
can anybody explain copy constructor. i need to understand the basics. if you give pseuodocode along with commentation, it may help to understand.
thanks
can anybody explain copy constructor. i need to understand the basics. if you give pseuodocode along with commentation, it may help to understand.
thanks
A copy constructor creates a new object as a copy of the object that you pass in. As an approximation, it's like creating a new object and using the assignment operator to create a copy of your first object. The copy constructor is mostly used "behind the scenes" when you copy data into (or return data from) a method, but you can of course use it explicitly in your program.
A copy CTOR is defined like this:
MyObject(const MyObject& o);
You pass in a reference to the object that needs to be copies (if you wouldn't use the reference, you would need a copy constructor, which isn't there yet), and you define the parameter as const, because it does not get modified in the CTOR. The copy CTOR (like a normal CTOR) does not return anything.
For the longer explanation, check out Lakshman's links.
A copy CTOR is defined like this:
MyObject(const MyObject& o);
You pass in a reference to the object that needs to be copies (if you wouldn't use the reference, you would need a copy constructor, which isn't there yet), and you define the parameter as const, because it does not get modified in the CTOR. The copy CTOR (like a normal CTOR) does not return anything.
For the longer explanation, check out Lakshman's links.
ASKER
if i write
myclass s = a; // a,s are objects of myclass
but DO NOT define constructor MyObject(const MyObject& o); then will the object be copied by default ???
does it mean compiler has a default copy-constructor if it dont find the user defined copy constructor like the above syntax ?
myclass s = a; // a,s are objects of myclass
but DO NOT define constructor MyObject(const MyObject& o); then will the object be copied by default ???
does it mean compiler has a default copy-constructor if it dont find the user defined copy constructor like the above syntax ?
ASKER
sorry two class name is different in my above post(i.e MyObject and myclass)....but u understand what i mean.
In this case, you will use the assignment operator=() and not the copy constructor, the copy constructor is used when you use something like this:
myclass s(a); // a is the already existing object that you want to copy.
The compiler will create both a default assignment operator and a default copy constructor, but both of them will use a byte by byte copy of the source. This will of course cause problems if you have pointers or objects in your source object.
myclass s(a); // a is the already existing object that you want to copy.
The compiler will create both a default assignment operator and a default copy constructor, but both of them will use a byte by byte copy of the source. This will of course cause problems if you have pointers or objects in your source object.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
>> In this case, you will use the assignment operator=()
No. With
myclass s = a;
the copy constructor is called and not the assignment operator=(..).
That is different to this:
myclass s;
s = a; // Here operator=(..) gets called
Note, i forgot a semicolon at end of declaration of class B;
Regards, Alex
No. With
myclass s = a;
the copy constructor is called and not the assignment operator=(..).
That is different to this:
myclass s;
s = a; // Here operator=(..) gets called
Note, i forgot a semicolon at end of declaration of class B;
Regards, Alex
ASKER
>>>"Both cases a copy constructor will called either the one you did provide or a 'default' copy constructor making a copy of the storage. .."
hi, the main motto of copy constructor is to copy data between classes.
so , why do we define our copy constructor !! why not we take the help from the default copy constructor itself.
i dont know wheteher copy constructor has any other usage other than copying.
P.S > alex you helped me yesterday to find a 3 x 3 box neighbour of a matrix element.
is it possible to get all the neighbours (i.e 3 x 3 , 5 x 5 , 7 x 7 ) of (i,j)th element of the matrix using a LOOP ?
bcoz, currentli i am writing all the neighbours manually. if the mask size is bigger then it is very bad to write down all the neighbours manually. let the program find out its neighbours(3 x 3, 5 x 5, 7 x 7 etc). i think i have to take the help of a loop.
is it possible ? can you tell some tricks to find out 3 x 3 or 5 x 5 or 7 x 7 box neighbour of a matrix elemnt using loop or whatever for efficiency ?
thanks
hi, the main motto of copy constructor is to copy data between classes.
so , why do we define our copy constructor !! why not we take the help from the default copy constructor itself.
i dont know wheteher copy constructor has any other usage other than copying.
P.S > alex you helped me yesterday to find a 3 x 3 box neighbour of a matrix element.
is it possible to get all the neighbours (i.e 3 x 3 , 5 x 5 , 7 x 7 ) of (i,j)th element of the matrix using a LOOP ?
bcoz, currentli i am writing all the neighbours manually. if the mask size is bigger then it is very bad to write down all the neighbours manually. let the program find out its neighbours(3 x 3, 5 x 5, 7 x 7 etc). i think i have to take the help of a loop.
is it possible ? can you tell some tricks to find out 3 x 3 or 5 x 5 or 7 x 7 box neighbour of a matrix elemnt using loop or whatever for efficiency ?
thanks
>> so , why do we define our copy constructor !! why not we take the help from the default copy constructor itself.
As i told you, defaukt constructor is dump and copies all bits. However, you need a 'deep' copy where any pointers get a new storage to point to and not copying a storage that belongs to another member.
is it possible to get all the neighbours (i.e 3 x 3 , 5 x 5 , 7 x 7 ) of (i,j)th element of the matrix using a LOOP ?
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
vector<pair<int, int> >* getNeighbors( int matrixSize, BoxSize bs, int i, int j )
{
vector<pair<int, int> >* pV = new vector<pair<int, int> >; // Note there must be a space between > >
for ( int x = i - bs; x <= i + bs )
{
if (x < 0 || x >= matrixSize)
continue;
for ( int y = j - bs; y <= j + bs )
{
if (y < 0 || y >= matrixSize || (x == i && y == j))
continue;
pV->push_back(pair<int, int>(x, y));
}
}
return pV;
}
Tell me if you need more info.
Regards, Alex
As i told you, defaukt constructor is dump and copies all bits. However, you need a 'deep' copy where any pointers get a new storage to point to and not copying a storage that belongs to another member.
is it possible to get all the neighbours (i.e 3 x 3 , 5 x 5 , 7 x 7 ) of (i,j)th element of the matrix using a LOOP ?
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
vector<pair<int, int> >* getNeighbors( int matrixSize, BoxSize bs, int i, int j )
{
vector<pair<int, int> >* pV = new vector<pair<int, int> >; // Note there must be a space between > >
for ( int x = i - bs; x <= i + bs )
{
if (x < 0 || x >= matrixSize)
continue;
for ( int y = j - bs; y <= j + bs )
{
if (y < 0 || y >= matrixSize || (x == i && y == j))
continue;
pV->push_back(pair<int, int>(x, y));
}
}
return pV;
}
Tell me if you need more info.
Regards, Alex
ASKER
ohh God.....i am weak in TEMPLATES ( advanced data structure ), i was expecting very simple answer , may be in C . can you change the code in C or in C++ without templates...simply array.
at this stage i am not comfortable in Templates .Anyway, if you can convert using array (may be in C ) it would be good.
however many thanks....i am trying to understand your code.
thanks
at this stage i am not comfortable in Templates .Anyway, if you can convert using array (may be in C ) it would be good.
however many thanks....i am trying to understand your code.
thanks
ASKER
thanks alex....i think i am not giving the full material. Let me tell you explicitly what i am doing now.
1. i have a gaussian mask ( 5 x 5)
gauss1[5][5] = { {2,4,5,4,2},
{4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}
};
2. and i have a image 512 x 512
3. i am moving this mask on pixel to pixel (of course which has 5 x 5 neighbour) of the image and averaging like below........
for(i=2;i<510;i++)
for(j=2;j<510;j++)
{
image[i][j] = gauss1[0][0]*image1[i-2][j -2] + gauss1[0][1]*image1[i-2][j -1]+gauss1 [0][2]*ima ge1[i-2][j ]
+ gauss1[0][3]*image1[i-2][j +1] + gauss1[0][4]*image1[i-2][j +2];
gauss1[1][0]*image1[i-1][j -2] + gauss1[1][1]*image1[i-1][j -1]+gauss1 [1][2]*ima ge1[i-1][j ]
+ gauss1[1][3]*image1[i-1][j +1] + gauss1[1][4]*image1[i-1][j +2];
gauss1[2][0]*image1[i][j-2 ] + gauss1[2][1]*image1[i][j-1 ]+gauss1[2 ][2]*image 1[i][j]
+ gauss1[2][3]*image1[i][j+1 ] + gauss1[2][4]*image1[i][j+2 ];
gauss1[3][0]*image1[i+1][j -2] + gauss1[3][1]*image1[i+1][j -1]+gauss1 [3][2]*ima ge1[i+1][j ]
+ gauss1[3][3]*image1[i+1][j +1] + gauss1[3][4]*image1[i+1][j +2];
+gauss1[4][0]*image1[i+2][ j-2] + gauss1[4][1]*image1[i+2][j -1]+gauss1 [4][2]*ima ge1[i+2][j ]
+gauss1[4][3]*image1[i+2][ j+1] + gauss1[4][4]*image1[i+2][j +2];
}
and replacing the centre elemnt by the sum value....
my question
-----------------
can i make the above code compact , shorter ?? this is my purpose.
thanks
1. i have a gaussian mask ( 5 x 5)
gauss1[5][5] = { {2,4,5,4,2},
{4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}
};
2. and i have a image 512 x 512
3. i am moving this mask on pixel to pixel (of course which has 5 x 5 neighbour) of the image and averaging like below........
for(i=2;i<510;i++)
for(j=2;j<510;j++)
{
image[i][j] = gauss1[0][0]*image1[i-2][j
+ gauss1[0][3]*image1[i-2][j
gauss1[1][0]*image1[i-1][j
+ gauss1[1][3]*image1[i-1][j
gauss1[2][0]*image1[i][j-2
+ gauss1[2][3]*image1[i][j+1
gauss1[3][0]*image1[i+1][j
+ gauss1[3][3]*image1[i+1][j
+gauss1[4][0]*image1[i+2][
+gauss1[4][3]*image1[i+2][
}
and replacing the centre elemnt by the sum value....
my question
-----------------
can i make the above code compact , shorter ?? this is my purpose.
thanks
I remember you only wanted neighbors that have an Image pointer not equal to NULL??
Ok.
#include <iostream>
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
class Image
{
void* pImg;
public:
Image() : pImg(NULL) {}
};
struct Cell
{
int x;
int y;
Cell(int xx, int yy) : x(xx), y(yy) {}
Cell() : x(-1), y(-1) {}
bool isValid() { return (x >= 0 && y >= 0); }
};
#define MATRIX_SIZE 1024
typedef Image* ImageMatrix[MATRIX_SIZE][M ATRIX_SIZE ];
Cell* getNeighbors( ImageMatrix& matrix, int matrixSize, BoxSize bs, int i, int j )
{
Cell* pNeighbors = new Cell[(bs+2)*(bs+2)]; // the array size is one greater than we need. The last cell always is invalid, thus terminating the array
int count = 0;
for ( int x = i - bs; x <= i + bs; x++ )
{
if (x < 0 || x >= matrixSize)
continue;
for ( int y = j - bs; y <= j + bs; y++ )
{
if (y < 0 || y >= matrixSize || (x == i && y == j))
continue;
if (matrix[x][y] == NULL)
continue;
pNeighbors[count].x = x;
pNeighbors[count].y = y;
count++;
}
}
return pNeighbors;
}
// You may use it like this:
void main()
{
ImageMatrix matrix = { NULL };
// fill matrix somehow
//....
// get i, j from somewhere
//...
int i = 17;
int j = 253;
// get all neighbors of a 5x5 box
Cell* neighbors = getNeighbors(matrix, MATRIX_SIZE, Box_5x5, i, j);
int count = 0;
while ( neighbors[count].isValid() )
{
int x = neighbors[count].x;
int y = neighbors[count].y;
// now x, y are the coordinates of a valid neighbor
// ....
count++;
}
delete [] neighbors;
}
BTW, you must not be good in templates, just use them. What i've used in my first example was a vector - that is a dynamic array - of integer pairs, where one pair holds the x, y coordinates of one of the neighbors. Without template classes i had to create a new struct/class called Cell that does the same as pair<int, int> - or better that does less. Furthermore, i had to define a 'isValid' function to be able to find out when there are no more Cell elements left in array.
Hope, that helps
Alex
Ok.
#include <iostream>
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
class Image
{
void* pImg;
public:
Image() : pImg(NULL) {}
};
struct Cell
{
int x;
int y;
Cell(int xx, int yy) : x(xx), y(yy) {}
Cell() : x(-1), y(-1) {}
bool isValid() { return (x >= 0 && y >= 0); }
};
#define MATRIX_SIZE 1024
typedef Image* ImageMatrix[MATRIX_SIZE][M
Cell* getNeighbors( ImageMatrix& matrix, int matrixSize, BoxSize bs, int i, int j )
{
Cell* pNeighbors = new Cell[(bs+2)*(bs+2)]; // the array size is one greater than we need. The last cell always is invalid, thus terminating the array
int count = 0;
for ( int x = i - bs; x <= i + bs; x++ )
{
if (x < 0 || x >= matrixSize)
continue;
for ( int y = j - bs; y <= j + bs; y++ )
{
if (y < 0 || y >= matrixSize || (x == i && y == j))
continue;
if (matrix[x][y] == NULL)
continue;
pNeighbors[count].x = x;
pNeighbors[count].y = y;
count++;
}
}
return pNeighbors;
}
// You may use it like this:
void main()
{
ImageMatrix matrix = { NULL };
// fill matrix somehow
//....
// get i, j from somewhere
//...
int i = 17;
int j = 253;
// get all neighbors of a 5x5 box
Cell* neighbors = getNeighbors(matrix, MATRIX_SIZE, Box_5x5, i, j);
int count = 0;
while ( neighbors[count].isValid()
{
int x = neighbors[count].x;
int y = neighbors[count].y;
// now x, y are the coordinates of a valid neighbor
// ....
count++;
}
delete [] neighbors;
}
BTW, you must not be good in templates, just use them. What i've used in my first example was a vector - that is a dynamic array - of integer pairs, where one pair holds the x, y coordinates of one of the neighbors. Without template classes i had to create a new struct/class called Cell that does the same as pair<int, int> - or better that does less. Furthermore, i had to define a 'isValid' function to be able to find out when there are no more Cell elements left in array.
Hope, that helps
Alex
Sorry, i missed your last comment. So my last comment answers your previous question (Gauss isn't involved yet).
I'll need some more minutes as i try to compile the solution before posting.
Regards, Alex
I'll need some more minutes as i try to compile the solution before posting.
Regards, Alex
#include <iostream>
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
#define MATRIX_SIZE 512
typedef int ImageMatrix[MATRIX_SIZE][M ATRIX_SIZE ];
// You may use it like this:
void main()
{
ImageMatrix image = { NULL };
// fill matrix somehow
//....
int gauss5[5][5] =
{
{2,4,5,4,2},
{ 4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}
};
int i, j, x, y;
BoxSize bs = Box_5x5;
for(i = bs; i < MATRIX_SIZE - bs; i++)
{
for(j = bs; j < MATRIX_SIZE - bs; j++)
{
int temp = 0;
for ( x = i - bs; x <= i + bs; x++ )
{
for ( y = j - bs; y <= j + bs; y++ )
{
temp += gauss5[x - (i - bs)][y - (j - bs)] * image[x][y];
}
}
image[x][y] = temp;
}
}
}
Note, now it is only a solution for a 5x5 box. However, if you would provied gauss numbers for 3x3 and 7x7 also, you can make the loop independent of the size of the box by this:
#include <iostream>
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
#define MATRIX_SIZE 512
typedef int ImageMatrix[MATRIX_SIZE][M ATRIX_SIZE ];
// You may use it like this:
void main()
{
ImageMatrix image = { NULL };
// fill matrix somehow
//....
int gauss_3x3[9] =
{ 1, 2, 1,
2, 4, 2,
1, 2, 1
};
int gauss_5x5[25] =
{
2,4,5,4,2,
4,9,12,9,4,
5,12,15,12,5,
4,9,12,9,4,
2,4,5,4,2
};
int gauss_7x7[49] =
{
2,4,5,9,5,4,2,
4,9,12,15,12,9,4,
5,12,15,21,15,12,5,
7,17,25,31,25,17,7,
5,12,15,21,15,12,5,
4,9,12,9,4,
2,4,5,4,2
};
int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
int i, j, x, y;
BoxSize bs = Box_5x5;
for(i = bs; i < MATRIX_SIZE - bs; i++)
{
for(j = bs; j < MATRIX_SIZE - bs; j++)
{
int temp = 0;
for ( x = i - bs; x <= i + bs; x++ )
{
for ( y = j - bs; y <= j + bs; y++ )
{
temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
}
}
image[x][y] = temp;
}
}
}
Regards, Alex
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
#define MATRIX_SIZE 512
typedef int ImageMatrix[MATRIX_SIZE][M
// You may use it like this:
void main()
{
ImageMatrix image = { NULL };
// fill matrix somehow
//....
int gauss5[5][5] =
{
{2,4,5,4,2},
{ 4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}
};
int i, j, x, y;
BoxSize bs = Box_5x5;
for(i = bs; i < MATRIX_SIZE - bs; i++)
{
for(j = bs; j < MATRIX_SIZE - bs; j++)
{
int temp = 0;
for ( x = i - bs; x <= i + bs; x++ )
{
for ( y = j - bs; y <= j + bs; y++ )
{
temp += gauss5[x - (i - bs)][y - (j - bs)] * image[x][y];
}
}
image[x][y] = temp;
}
}
}
Note, now it is only a solution for a 5x5 box. However, if you would provied gauss numbers for 3x3 and 7x7 also, you can make the loop independent of the size of the box by this:
#include <iostream>
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
#define MATRIX_SIZE 512
typedef int ImageMatrix[MATRIX_SIZE][M
// You may use it like this:
void main()
{
ImageMatrix image = { NULL };
// fill matrix somehow
//....
int gauss_3x3[9] =
{ 1, 2, 1,
2, 4, 2,
1, 2, 1
};
int gauss_5x5[25] =
{
2,4,5,4,2,
4,9,12,9,4,
5,12,15,12,5,
4,9,12,9,4,
2,4,5,4,2
};
int gauss_7x7[49] =
{
2,4,5,9,5,4,2,
4,9,12,15,12,9,4,
5,12,15,21,15,12,5,
7,17,25,31,25,17,7,
5,12,15,21,15,12,5,
4,9,12,9,4,
2,4,5,4,2
};
int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
int i, j, x, y;
BoxSize bs = Box_5x5;
for(i = bs; i < MATRIX_SIZE - bs; i++)
{
for(j = bs; j < MATRIX_SIZE - bs; j++)
{
int temp = 0;
for ( x = i - bs; x <= i + bs; x++ )
{
for ( y = j - bs; y <= j + bs; y++ )
{
temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
}
}
image[x][y] = temp;
}
}
}
Regards, Alex
ASKER
ok, thansk alex....i am reading your code... i need some time to see what u r doing...i will reply soon.
thanks
thanks
ASKER
sorry there was a typo in my earlier post in that big equn.
it should be.... image1[i][j] = gauss1[0][0]*image1[i-2][j -2] ....// bla bla..(NOT image[i][j])
it should be.... image1[i][j] = gauss1[0][0]*image1[i-2][j
>> image1/image
That doesn't matter. I called it image and as it compiled the compiler was happy with that name ;-)
Will give you some remarks on my code:
>> enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
That enum BoxSize are only integer constants. Maybe i should have called it better BoxRadius as it is the number of neighbors in any direction.
>>typedef int ImageMatrix[MATRIX_SIZE][M ATRIX_SIZE ];
That typedef makes it possible to pass the matrix to a function (as pointer or as reference) and use image[x][y] within the function. You should know that in C/C++ arrays are passed to functions as pointers. Th at means the array dimensions get lost and you would get a compiler error when using image[x][y] as the compiler doesn't know the size of the matrix. Using a typedef gives this information.
>> int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
I made a new array, where i stored the pointers to all (three) gaussian arrays. Thus gauss[0] == gauss_3x3, gauss[1] == gauss_5x5, gauss[2] == gauss_7x7
>> BoxSize bs = Box_5x5;
With that i made the loop independent of the box size; you may choose other Box values here and the loop must not be changed.
>> for(i = bs; i < MATRIX_SIZE - bs; i++)
The loop starts with bs == 2 and ends before MATRX_SIZE-bs == 510.
>> int temp = 0;
As the box calculations were done in a loop i need a temporary integer where the sum can be added.
>> temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
That's maybe difficult? Ok, step by step:
>> gauss[bs-1]
You know bs == 2, so we are using gauss[1] == gauss_5x5.
>> (x - (i - bs))
x runs from i - bs to i + bs. So, at the beginning (x - (i - bs)) == 0 and finally it is (i + bs - (i - bs)) == (i + bs - i + bs) == bs + bs == 4. Sp the first term runs from 0 to 4 what is the x dimension of the 5x5 gauss array.
>> *(2*bs+1)
That term evaluates to (2*2+1) == 5, what is the box size. As i turned the 5x5 matrix to an array of size 25, i have to calculate the index using a * boxsize + b, where a == (x - (i - bs)) as described before and
>> (y - (j - bs))
is b. So, all that algorithm i a simple index calculation. BTW, are you good in mathematics?
Hope, it is clear now.
Regards, Alex
Regards, Alex
That doesn't matter. I called it image and as it compiled the compiler was happy with that name ;-)
Will give you some remarks on my code:
>> enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
That enum BoxSize are only integer constants. Maybe i should have called it better BoxRadius as it is the number of neighbors in any direction.
>>typedef int ImageMatrix[MATRIX_SIZE][M
That typedef makes it possible to pass the matrix to a function (as pointer or as reference) and use image[x][y] within the function. You should know that in C/C++ arrays are passed to functions as pointers. Th at means the array dimensions get lost and you would get a compiler error when using image[x][y] as the compiler doesn't know the size of the matrix. Using a typedef gives this information.
>> int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
I made a new array, where i stored the pointers to all (three) gaussian arrays. Thus gauss[0] == gauss_3x3, gauss[1] == gauss_5x5, gauss[2] == gauss_7x7
>> BoxSize bs = Box_5x5;
With that i made the loop independent of the box size; you may choose other Box values here and the loop must not be changed.
>> for(i = bs; i < MATRIX_SIZE - bs; i++)
The loop starts with bs == 2 and ends before MATRX_SIZE-bs == 510.
>> int temp = 0;
As the box calculations were done in a loop i need a temporary integer where the sum can be added.
>> temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
That's maybe difficult? Ok, step by step:
>> gauss[bs-1]
You know bs == 2, so we are using gauss[1] == gauss_5x5.
>> (x - (i - bs))
x runs from i - bs to i + bs. So, at the beginning (x - (i - bs)) == 0 and finally it is (i + bs - (i - bs)) == (i + bs - i + bs) == bs + bs == 4. Sp the first term runs from 0 to 4 what is the x dimension of the 5x5 gauss array.
>> *(2*bs+1)
That term evaluates to (2*2+1) == 5, what is the box size. As i turned the 5x5 matrix to an array of size 25, i have to calculate the index using a * boxsize + b, where a == (x - (i - bs)) as described before and
>> (y - (j - bs))
is b. So, all that algorithm i a simple index calculation. BTW, are you good in mathematics?
Hope, it is clear now.
Regards, Alex
Regards, Alex
ASKER
thanks alex, you have caught me...you are right .exactly i had problems on those typical areas.so, i was thinking and taking time.
by the time, i liked your first code( 5x 5 only) bcoz it was very simple and i went ahead to implement on my data.......but my output data file is not consistent which should not be theoretically.
ok, i am gving the code below....
[code]
#include<iostream>
#include<cstdlib>
#include<fstream>
using namespace std;
#define MATRIX_SIZE 512
int main()
{
ifstream fin("c:\\lena1.pgm");
ofstream fout("c:\\filtered_image.p
int x;
static int image[512][512];
if(!fin.is_open() ) { cout<<"error"; return EXIT_FAILURE; }
for(int i=0;i<512;i++)
for(int j=0;j<512;j++)
{
fin>>x;
image[i][j]= x; // load the image
}
int gauss5[5][5] =
{
{2,4,5,4,2},
{ 4,9,12,9,4},
{5,12,15,12,5},
{4,9,12,9,4},
{2,4,5,4,2}
};
enum BoxSize { Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
int j,y;
BoxSize bs = Box_5x5;
for(i = bs; i < MATRIX_SIZE - bs; i++)
{
for(j = bs; j < MATRIX_SIZE - bs; j++)
{
int temp = 0;
for ( x = i - bs; x <= i + bs; x++ )
{
for ( y = j - bs; y <= j + bs; y++ )
{
temp += gauss5[x - (i - bs)][y - (j - bs)] * image[x][y];
}
}
image[i][j] = temp/115; // 115 is the normalization factor of the 5 x5 matrix
}
}
for(int k =0;k<512;k++)
for(int l=0;l<512;l++)
{
fout<<"\t"<<image[i][j];
}
}
[/code]
my output
------------
i am getting output data file which is full of only integer number 105 ..i.e there are all total 512 x 512 integers. each of them are 105 . is not it strange ? it should not be theoretically. my implementation has gone wrong. i could not find out whats wrong in my code.
but Definitely something wrong in the code bcoz output file can not have all the same numbers. can you suggest what could be wrong in the above code ?
thanks, i am concentrating on your new comments and waiting for reply.
P.S : i have changed image[x][y] to image[i][j] bcoz i will change the centre pixel of the box by the new value.
That's easy. look at your output loop; your counters are k and l while youtur output indexes are i and j.
for(int k =0;k<512;k++)
for(int l=0;l<512;l++)
{
fout<<"\t"<<image[i][j];
}
Change line to
fout<<"\t"<<image[k][l];
and it should work. Depending on input file hasn't all the same integer though ;-)
Regards, Alex
Regards, Alex
BTW, you could easily change to the 'advanced' solution, that will most likely produce same output.
for(int k =0;k<512;k++)
for(int l=0;l<512;l++)
{
fout<<"\t"<<image[i][j];
}
Change line to
fout<<"\t"<<image[k][l];
and it should work. Depending on input file hasn't all the same integer though ;-)
Regards, Alex
Regards, Alex
BTW, you could easily change to the 'advanced' solution, that will most likely produce same output.
>> P.S : i have changed image[x][y] to image[i][j] bcoz i will change the centre pixel of the box by the new value.
Good, that was a copy-paste error that i made...
>> #define MATRIX_SIZE 512
You should replace 512 by MATRIX_SIZE, that is good practice and makes it easier to change sizes.
Regards, Alex
Good, that was a copy-paste error that i made...
>> #define MATRIX_SIZE 512
You should replace 512 by MATRIX_SIZE, that is good practice and makes it easier to change sizes.
Regards, Alex
ASKER
>>That's easy. look at your output loop; your counters are k and l while youtur output indexes are i and j.
ooops....i did not notice it . ok thanks. i will fix it.
>>Depending on input file hasn't all the same integer though.
input file is perfectly valid. and good looking image having numbers in between 0-255. its ok.
i will try tomorrow to fix .
>>you could easily change to the 'advanced' solution, that will most likely produce same output.
i need some time to sleep now . tomorrow morning i will go for the advanced soln and fix the above errors.
thanks
ooops....i did not notice it . ok thanks. i will fix it.
>>Depending on input file hasn't all the same integer though.
input file is perfectly valid. and good looking image having numbers in between 0-255. its ok.
i will try tomorrow to fix .
>>you could easily change to the 'advanced' solution, that will most likely produce same output.
i need some time to sleep now . tomorrow morning i will go for the advanced soln and fix the above errors.
thanks
ASKER
hi alex,
i have fixed the erros. and implemented on my image data and got filtered image .implementation is ok. it is working perfectly.
i have taken up your old soln and added some codes also.
one more thing i want make the code smarter.
CAN i do a use-interactivity with code ? so that the user will input what box size he wants.
i want something like below...of course it is not working
int x;
cout<<"plz enter the BOXSIZE number..... 1 (for 5x5) , 2 (for 7x 7) "<<endl;
cin>>x;
BoxSize bs = x // here is the problem...compiler gives error... .enum and int are conflicting
which way i would write so that user can give his choice.
thanks
i have fixed the erros. and implemented on my image data and got filtered image .implementation is ok. it is working perfectly.
i have taken up your old soln and added some codes also.
one more thing i want make the code smarter.
CAN i do a use-interactivity with code ? so that the user will input what box size he wants.
i want something like below...of course it is not working
int x;
cout<<"plz enter the BOXSIZE number..... 1 (for 5x5) , 2 (for 7x 7) "<<endl;
cin>>x;
BoxSize bs = x // here is the problem...compiler gives error... .enum and int are conflicting
which way i would write so that user can give his choice.
thanks
enum BoxSize { Box_Invalid = -1, Box_3x3 = 1, Box_5x5 = 2, Box_7x7 = 3 };
BoxSize bs = Box_Invalid;
int x;
while (bs == Box_Invalid)
{
cout<<"plz enter the BOXSIZE number..... 5 (for 5x5) , 7 (for 7x 7) "<<endl;
cin>>x;
bs = (x == 5)? Box_5x5 : (x == 7)? Box_7x7 : Box_Invalid;
if (bs == Box_Invalid)
{
cout << "It isn't difficult to enter either 5 or 7, try again.." << endl;
}
}
Regards, Alex
ASKER
bravo, great....you have tackled very clever way. now i see there will be no data type conflict.
this must work certainly.
i read your advanced solution....i am getting the points.
can i ask you one more silly question.
you have written
int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
is it a valid syntax ? bcoz your content of the array are matrices. so my recomendation is
int** gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 }; // double *
bcoz matrix is written int ** matrix.
i am not sure whether i am correct in this context .
anyway, thanks for the clarification, solution and great help.
this must work certainly.
i read your advanced solution....i am getting the points.
can i ask you one more silly question.
you have written
int* gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 };
is it a valid syntax ? bcoz your content of the array are matrices. so my recomendation is
int** gauss[3] = { gauss_3x3, gauss_5x5, gauss_7x7 }; // double *
bcoz matrix is written int ** matrix.
i am not sure whether i am correct in this context .
anyway, thanks for the clarification, solution and great help.
is it a valid syntax ?
My Compiler said, yes.
Look at the definition of gauss_3x3, ... I serialized them to an array, just adding line by line.
The reason for this was to be able to put them into that gauss[] array. If i have three matrices, each different in the x size, i wouldn't be able to store them to a common array. But i need t that array for this statement:
temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
if i had three matrices i would have change it to
if (bs == Box_3x3)
temp += gauss_3x3[x-(i-bs)][y-(i-b s];
else if (bs == Box_5x5)
temp += gauss_5x5[x-(i-bs)][y-(i-b s];
else
temp += gauss_7x7[x-(i-bs)][y-(i-b s];
Not bad, but the other is better.
Regards, Alex
My Compiler said, yes.
Look at the definition of gauss_3x3, ... I serialized them to an array, just adding line by line.
The reason for this was to be able to put them into that gauss[] array. If i have three matrices, each different in the x size, i wouldn't be able to store them to a common array. But i need t that array for this statement:
temp += gauss[bs-1][(x - (i - bs))*(2*bs+1) + y - (j - bs)] * image[x][y];
if i had three matrices i would have change it to
if (bs == Box_3x3)
temp += gauss_3x3[x-(i-bs)][y-(i-b
else if (bs == Box_5x5)
temp += gauss_5x5[x-(i-bs)][y-(i-b
else
temp += gauss_7x7[x-(i-bs)][y-(i-b
Not bad, but the other is better.
Regards, Alex
http://www.stanford.edu/class/cs193d/Handouts/06-Copy-Constructors.pdf
and
https://www.experts-exchange.com/questions/10224321/copy-constructor.html
-Lakshman