1. Randomly generates triangles.
2. Draws the triangles on an image.
3. Checks to see if that new triangle makes the triangle generated image closer to the target image.
4. If it is closer to the target image, keep the triangle and go back to 1, else revert back to image state without the last triangle and try again (goto 1).
However, when I run this code in Ubuntu on a dual-core system after a long while (say past 500 triangle additions) some weird behavior starts happening. When it is running normally top will show me two threads running at nearly 100%, however once the weird behavior starts happening one thread disappears leaving only one thread running at 100%. Even though this thread appears to be running in top, the program is stalled and does not continue to progress not matter how long I wait. The program itself has shown no signs of crashing. If I try to kill the remaining process using "kill -9" the process does not terminate. In fact not matter what I try, including pressing ctrl-c and closing the terminal window in which the program is running, I can not kill this process. Even if I try to shutdown or reset my computer the computer hangs and I have to power cycle the machine. This behavior happens every single time I run the program for a long duration on my dual-core machine but not at exactly the same spot in terms of triangles added. I have never had crashes or behavior like this before on this machine. I also have a FreeBSD box, which uses a older single core processor and when I run this program on the FreeBSD machine I have not experienced these problems at all.
Code: Select all
#include <iostream>
#include <list>
#include <cstdlib>
#include <ctime>
#include <Magick++.h>
#include <vector>
#include <cstring>
#include <cassert>
using namespace std;
using namespace Magick;
const char background[] = "black";
const double opacity = 1;
inline void drawTriangle(Image &img, const vector<unsigned int> &triangle){
char cmdBuffer[128];
list<Coordinate> points(3);
sprintf(cmdBuffer, "rgba(%u, %u, %u, %lf)", triangle[0], triangle[1], triangle[2], opacity);
img.fillColor(cmdBuffer);
list<Coordinate>::iterator it = points.begin();
it->x(triangle[3]);
it->y(triangle[4]);
it++;
it->x(triangle[5]);
it->y(triangle[6]);
it++;
it->x(triangle[7]);
it->y(triangle[8]);
img.draw(DrawablePolygon(points));
}
int main(int argc, char **argv){
Image targetImage, finalImage, workingImage, bestImage;
Geometry targetGeometry;
unsigned int i, numTriangles;
vector<unsigned int> triangle(9);
double bestError;
srand(time(NULL));
if (argc != 3){
cout << "polypic <filename> <#triangles>" << endl;
return 1;
}
try{
targetImage.read(argv[1]);
numTriangles = atoi(argv[2]);
targetGeometry = targetImage.size();
workingImage = Image(targetGeometry, background);
bestImage = Image(targetGeometry, background);
finalImage = Image(Geometry(targetGeometry.width() * 2, targetGeometry.height()), background);
finalImage.composite(targetImage, 0, 0);
targetImage.compare(workingImage);
bestError = targetImage.meanErrorPerPixel();
for (i = 0; i < numTriangles; i++){
do{
workingImage = bestImage;
triangle[0] = rand() % 256;
triangle[1] = rand() % 256;
triangle[2] = rand() % 256;
triangle[3] = rand() % targetGeometry.width();
triangle[4] = rand() % targetGeometry.height();
triangle[5] = rand() % targetGeometry.width();
triangle[6] = rand() % targetGeometry.height();
triangle[7] = rand() % targetGeometry.width();
triangle[8] = rand() % targetGeometry.height();
drawTriangle(workingImage, triangle);
targetImage.compare(workingImage);
} while(targetImage.meanErrorPerPixel() >= bestError);
bestError = targetImage.meanErrorPerPixel();
bestImage = workingImage;
cout << i << ". " << bestError << endl;
}
finalImage.composite(bestImage, targetGeometry.width(), 0);
finalImage.write("final1.png");
}
catch(exception &error_){
cout << "Caught exception: " << error_.what() << endl;
return 1;
}
return 0;
}