This function in the Game of Life assignment is supposed to loop through the 2nd array and check to see how many neighbors each cell has. When I call this in the main, not even in any sort of loop, the terminal freezes as if in an infinite while loop. Can anyone tell me what's wrong with my code? Thanks.
void Grids::simulate(int** myGrid, int rows, int columns)
{
int neighbors = 0; //variable to store how many neighbors a cell has
for (int r = 0; r < rows; ++r) // iterates through rows
{
for(int c = 0; c < columns; ++c)//iterates through columns
{
for(int x = -1; x < 2; x + 2) //iterates through -1 and 1, the spaces next to the cell
{
for(int y = -1; y < 2; y + 2)
{
if ((r + x >= 0) && (r + x < rows) && (c + y >= 0) && (c + y < columns)) //prevents indexing the 2d array outside of its bounds
{
if (myGrid[r + x][c + y] == 1) //checks if the surrounding cells are alive
{
++neighbors;
}
}
}
}
if (neighbors < 2) //underpopulation
{
myGrid[r][c] = 0; //dead
}
else if (neighbors == 3) //reproduction
{
myGrid[r][c] = 1; //alive
}
else if (neighbors >= 4) //overpopulation
{
myGrid[r][c] = 0; //dead
}
}
}
}
You should change this x + 2 to x += 2 and y + 2 to y += 2, to make the loop increase by 2 each cycle. I also advise you to remove extra parentheses in this line if (r + x >= 0 && r + x < rows && c + y >= 0 && c + y < columns).
I am trying to implement Laplace sharpening using C++ , here's my code so far:
img = imread("cow.png", 0);
Mat convoSharp() {
//creating new image
Mat res = img.clone();
for (int y = 0; y < res.rows; y++) {
for (int x = 0; x < res.cols; x++) {
res.at<uchar>(y, x) = 0.0;
}
}
//variable declaration
int filter[3][3] = { {0,1,0},{1,-4,1},{0,1,0} };
//int filter[3][3] = { {-1,-2,-1},{0,0,0},{1,2,1} };
int height = img.rows;
int width = img.cols;
int filterHeight = 3;
int filterWidth = 3;
int newImageHeight = height - filterHeight + 1;
int newImageWidth = width - filterWidth + 1;
int i, j, h, w;
//convolution
for (i = 0; i < newImageHeight; i++) {
for (j = 0; j < newImageWidth; j++) {
for (h = i; h < i + filterHeight; h++) {
for (w = j; w < j + filterWidth; w++) {
res.at<uchar>(i,j) += filter[h - i][w - j] * img.at<uchar>(h,w);
}
}
}
}
//img - laplace
for (int y = 0; y < res.rows; y++) {
for (int x = 0; x < res.cols; x++) {
res.at<uchar>(y, x) = img.at<uchar>(y, x) - res.at<uchar>(y, x);
}
}
return res;
}
I don't really know what went wrong, I also tried different filter (1,1,1),(1,-8,1),(1,1,1) and the result is also same (more or less). I don't think that I need to normalize the result because the result is in range of 0 - 255. Can anyone explain what really went wrong in my code?
Problem: uchar is too small to hold partial results of filerting operation.
You should create a temporary variable and add all the filtered positions to this variable then check if value of temp is in range <0,255> if not, you need to clamp the end result to fit <0,255>.
By executing below line
res.at<uchar>(i,j) += filter[h - i][w - j] * img.at<uchar>(h,w);
partial result may be greater than 255 (max value in uchar) or negative (in filter you have -4 or -8). temp has to be singed integer type to handle the case when partial result is negative value.
Fix:
for (i = 0; i < newImageHeight; i++) {
for (j = 0; j < newImageWidth; j++) {
int temp = res.at<uchar>(i,j); // added
for (h = i; h < i + filterHeight; h++) {
for (w = j; w < j + filterWidth; w++) {
temp += filter[h - i][w - j] * img.at<uchar>(h,w); // add to temp
}
}
// clamp temp to <0,255>
res.at<uchar>(i,j) = temp;
}
}
You should also clamp values to <0,255> range when you do the subtraction of images.
The problem is partially that you’re overflowing your uchar, as rafix07 suggested, but that is not the full problem.
The Laplace of an image contains negative values. It has to. And you can’t clamp those to 0, you need to preserve the negative values. Also, it can values up to 4*255 given your version of the filter. What this means is that you need to use a signed 16 bit type to store this output.
But there is a simpler and more efficient approach!
You are computing img - laplace(img). In terms of convolutions (*), this is 1 * img - laplace_kernel * img = (1 - laplace_kernel) * img. That is to say, you can combine both operations into a single convolution. The 1 kernel that doesn’t change the image is [(0,0,0),(0,1,0),(0,0,0)]. Subtract your Laplace kernel from that and you obtain [(0,-1,0),(-1,5,-1),(0,-1,0)].
So, simply compute the convolution with that kernel, and do it using int as intermediate type, which you then clamp to the uchar output range as shown by rafix07.
In opencv c++ I'm trying to figure out how to calculate the euclidean distance between point i,j and all points within a 3x3 kernel. This is to create a contrast map of saliency from the Luv color space. I've also tried the norm function to no avail. I'm very confused as to how to solve this problem and would appreciate some feedback.
Mat tmp1 = MeanShift_Luv.clone();
int big_theta = 3; // kernel size / neighborhood to perform convolution on
Mat gradient_1 = Mat::zeros(tmp1.rows, tmp1.cols, CV_64FC3);
for (int i = 0; i < tmp1.rows; i++){
for (int j = 0; j < tmp1.cols; j++){
double dist = 0;
for (int m = -big_theta / 2; m < big_theta / 2; m++){
for(int n = -big_theta /2; n < big_theta / 2; n++){
if (m == 0 || n == 0) continue;
if (i + m < 0 || i + m >= tmp1.rows) continue;
if (j + n < 0 || j + n >= tmp1.cols) continue;
/* unsure what to do at this part
Point a(i,j);
Point b(i+m, j+n);
*/
}
}
gradient_1.at<Vec3d>(i,j) = dist;
}
Integer Range = 1;
for(Integer k = -Range; k <= Range; ++k)
{
for(Integer j = -Range; j <= Range; ++j)
{
for(Integer i = -Range; i <= Range; ++i)
{
Integer MCID = GetCellID(&CONSTANT_BOUNDINGBOX,CIDX +i, CIDY + j,CIDZ
+ k);
if(MCID < 0 || MCID >= c_CellNum)
{
continue;
}
unsigned int TriangleNum = c_daCell[MCID].m_TriangleNum;
for(unsigned int l = 0; l < TriangleNum; ++l)
{
TriangleID=c_daCell[MCID].m_TriangleID[l];
if( TriangleID >= 0 && TriangleID < c_TriangleNum && TriangleID
!= NearestID)// No need to calculate again for the same triangle
{
CDistance Distance ;
Distance.Magnitude = CalcDistance(&c_daTriangles[TriangleID], &TargetPosition,
&Distance.Direction);
if(Distance.Magnitude < NearestDistance.Magnitude)
{
NearestDistance = Distance;
NearestID = TriangleID;
}
}
}
}
}
}
}
c_daSTLDistance[ID] = NearestDistance;
c_daSTLID[ID] = NearestID;
GetCellID is the function to return the cellid in the variable CID with CIDX,CIDY,CIDZ with its position in the 3 axes
here the above code is a function to calculate the distance ,actually STL distance between a point and the triangles of the stl. This code runs fine however the problem is it is too slow as it has large number of loops within the code. Now my concern is to optimize the loop. Is there any technique of optimizing the loops within the code?
I have started to study algorithms and software development and, as a small self evaluation project I have decided to write the A* search algorithm in C++. It uses Qt and OpenGL for the visual part (but that is not important).
Using mostly this source:
A* Pathfinding for Beginners
I have write a small app, however I am have found a bug that I cant fix. It appears that for some reason the parent of a node close to the wall is set to the wall.(?) And the parent of the wall is set to the the start point(?) because of the way I am storing the info.
I have used a stateMatrix[][] where
1 = entrance green;
2 = exit;
3 = wall and;
4 = path;
I have also used matrix to represent openNodes and closedNode. The closedNodes matrix is bool matrix the openNode matrix also stores some info:
The openNodes instructions are:
openNodes[100][100][6];
0 - bool open or closed
1 - F
2 - G
3 - H
4 - parentX
5 - parentY
I know that there are better ways to code this but I have not yet got to this lesson ;)
Here is the code of the astar file:
#include <math.h>
#include "apath.h"
aPath::aPath()
{
gridSize = 100;
int i, j, k;
for(i = 0; i < gridSize; i++)
for(j = 0; j < gridSize; j++)
{
stateMatrix[i][j] = 0;
for(int k = 0; k < 6; k++) openNodes[i][j][k] = 0;
closedNodes[i][j] = 0;
}
targetX = targetY =
openX = openY = entranceX = entranceY = 0;
}
void aPath::start()
{
bool testOK = false;
int G = 0;
openNodes[entranceX][entranceY][0] = 1;
openNodes[entranceX][entranceY][2] = 14;
openNodes[entranceX][entranceY][3] = euclidean(entranceX,
entranceY);
openNodes[entranceX][entranceY][1] =
openNodes[entranceX][entranceY][2] +
openNodes[entranceX][entranceY][3];
openNodes[entranceX][entranceY][4] = entranceX;
openNodes[entranceX][entranceY][5] = entranceY;
int i, j, x, y;
while(closedNodes[targetX][targetY] == 0)
{
searchLessOpen();
closedNodes[openX][openY] = 1;
openNodes[openX][openY][0] = 0;
//Check the 8 squares around
for(i = openX - 1; i <= openX + 1; i++)
for(j = openY - 1; j <= openY + 1; j++)
{
//check if the square is in the limits,
//is not a wall and is not in the closed list
if((i >= 0) && (j >= 0) &&
(i < gridSize) && (j < gridSize) &&
(stateMatrix[i][j] != 3) &&
(closedNodes[i][j] == 0))
{
//G calculus. If it is in the edge it costs more
x = i - openX + 1;
y = j - openY + 1;
if((x == 0 && y == 0) ||
(x == 0 && y == 2) ||
(x == 2 && y == 0) ||
(x == 2 && y == 2))
{
G = 14;
}
else G = 10;
//check if node is already open
if(openNodes[i][j][0] == 0)
{
openNodes[i][j][0] = 1;
openNodes[i][j][2] = G;
openNodes[i][j][3] = euclidean(i,j);
openNodes[i][j][1] = openNodes[i][j][2] + openNodes[i][j][3];
openNodes[i][j][4] = openX;
openNodes[i][j][5] = openY;
}
else //if node is open, check if this path is better
{
if(G < openNodes[i][j][2])
{
openNodes[i][j][2] = G;
openNodes[i][j][1] = openNodes[i][j][2] + openNodes[i][j][3];
openNodes[i][j][4] = openX;
openNodes[i][j][5] = openY;
}
}
}
}
}
reconstruct();
}
void aPath::reconstruct()
{
bool test = false;
int x = openNodes[targetX][targetY][4];
int y = openNodes[targetX][targetY][5];
do
{
stateMatrix[x][y] = 4;
x = openNodes[x][y][4];
y = openNodes[x][y][5];
if(x == entranceX && y == entranceY) test = true;
} while(test == false);
}
int aPath::euclidean(int currentX, int currentY)
{
int dx = targetX - currentX;
int dy = targetY - currentY;
return 10*sqrt((dx*dx)+(dy*dy));
}
void aPath::searchLessOpen()
{
int F = 1000000;
int i, j;
for(i = 0; i < gridSize; i++)
for(j = 0; j < gridSize; j++)
{
if(openNodes[i][j][0] == 1)
{
if(openNodes[i][j][1] <= F)
{
F = openNodes[i][j][1];
openX = i;
openY = j;
}
}
}
}
Does anyone know what I am doing wrong?
Thanks.
Edit: Here are some pictures:
In aPath::start(), you have:
openNodes[entranceX][entranceY][0] = 1;
openNodes[entranceX][entranceY][2] = 14;
openNodes[entranceX][entranceY][3] = euclidean(entranceX,
entranceY);
openNodes[entranceX][entranceY][3] =
openNodes[entranceX][entranceY][2] +
openNodes[entranceX][entranceY][3];
openNodes[entranceX][entranceY][4] = entranceX;
openNodes[entranceX][entranceY][5] = entranceY;
Why is there no value for subscript [1]? And why do you assign two different values to subscript [3]? Also, to be honest, the entranceX and entranceY names are too long for the job they're doing; they make the code less readable (though I'm sure you were told to use good meaningful names). For these array indexes, I'd probably use just x and y.
At the code:
//Check the 8 squares around
for(i = openX - 1; i <= openX + 1; i++)
for(j = openY - 1; j <= openY + 1; j++)
{
I would probably ensure that neither i nor j took on invalid values with code such as:
//Check the 8 squares around (openX, openY)
int minX = max(openX - 1, 0);
int maxX = min(openX + 1, gridsize);
int minY = max(openY - 1, 0);
int maxY = min(openY + 1, gridsize);
for (i = minX; i <= maxX; i++)
for (j = minY; j <= maxY; j++)
{
I am not sure whether you need to explicitly check for the case where i == openX && j == openY (the current cell); it is not one of the 8 cells around the current cell (because it is the current cell), but the other conditions may already deal with that. If not:
if (i == openX && j == openY)
continue;
I note that we have no definitions of openX and openY or a number of other non-local variables. This makes it hard to work out whether they are class member variables or global variables of some sort. We also can't see how they're initialized, nor the documentation on what they represent.
Most plausible source of trouble
In aPath::SearchLessOpen(), you have:
if(openNodes[i][j][0] == 1)
{
if(openNodes[i][j][6] <= F)
{
F = openNodes[i][j][7];
You indicated in your description that the subscripts on openNodes in the last place ranged over 0..5; your code, though, is accessing subscripts 6 and 7. This could easily lead to the sort of confusion you describe - you are accessing data out of bounds. I think this might easily be the root of your trouble. When you access openNodes[i][j][6], this is technically undefined behaviour, but the most likely result is that it is reading the same data as if you'd written openNodes[i][j+1][0] (when j < gridsize - 1). Similarly, openNodes[i][j][7] is equivalent to accessing openNodes[i][j+1][1], with the same caveats.