Skip to content

Instantly share code, notes, and snippets.

@richard-to
Created April 8, 2014 00:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save richard-to/10078407 to your computer and use it in GitHub Desktop.
Save richard-to/10078407 to your computer and use it in GitHub Desktop.
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "opencv2/imgproc/imgproc.hpp"
using namespace cv;
using namespace std;
#define FILENAME_OUT "%s/frame%d.jpg"
#define TITLE "Capture Arm Movements"
#define ESC_KEY 27
#define DELAY 33
int main(int argc, char** argv)
{
if (argc < 2) {
printf("Usage: capture_arm output_folder\n");
exit(-1);
}
char filename_out[100];
char c;
int frame_count = 0;
Mat frame;
VideoCapture capture;
namedWindow(TITLE, WINDOW_AUTOSIZE);
capture.open(0);
if (!capture.isOpened()) {
cerr << "Couldn't open capture." << endl;
return -1;
}
capture >> frame;
while (frame.data) {
sprintf(filename_out, FILENAME_OUT, argv[1], ++frame_count);
imwrite(string(filename_out), frame);
imshow(TITLE, frame);
c = waitKey(DELAY);
if (c == ESC_KEY) {
break;
}
capture >> frame;
}
capture.release();
destroyWindow(TITLE);
};
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <string.h>
// Begin - Settings
#define DEBUG 1
#define DIFF_THRESH 40
#define DIFF_COLOR 255
#define THRESHOLD 200
#define FILENAME_IN "%s/frame%d.ppm"
#define FILENAME_OUT "%s/frame%d.pgm"
// End - Settings
#if DEBUG
#define LOG(a) printf a
#else
#define LOG(a) (void)0
#endif
#define PGM_HEADER_FORMAT "P5\n%d %d\n%d\n"
#define PBM_HEADER_FORMAT "P1\n%d %d\n"
#define WHITE 255
#define BLACK 0
#define P4_WHITE 0
#define P4_BLACK 1
#define P1_WHITE 48
#define P1_BLACK 49
#define PNM_LEX_DELIM '\n'
#define PNM_LEX_BEGIN_HEIGHT ' '
#define PNM_LEX_BEGIN_COMMENT '#'
enum PNM_LexerMode { PNM_TYPE, PNM_COMMENT, PNM_WIDTH, PNM_HEIGHT, PNM_COLORS };
enum PNM_Type { PNM_NONE, PNM_P1, PNM_P5, PNM_P6 };
typedef double FLOAT;
typedef unsigned int UINT32;
typedef unsigned long long int UINT64;
typedef unsigned char UINT8;
typedef struct _PNM_Meta {
char header[21];
unsigned int header_length = 0;
PNM_Type type = PNM_NONE;
int width = 0;
int height = 0;
int colors = 0;
} PNM_Meta;
static struct timeval t_diff, t_start, t_end, p_start, p_end, start, end;
// From: http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
int timeval_diff(timeval *result, timeval x, timeval y)
{
/* Perform the carry for the later subtraction by updating y. */
if (x.tv_usec < y.tv_usec) {
int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
y.tv_usec -= 1000000 * nsec;
y.tv_sec += nsec;
}
if (x.tv_usec - y.tv_usec > 1000000) {
int nsec = (x.tv_usec - y.tv_usec) / 1000000;
y.tv_usec += 1000000 * nsec;
y.tv_sec -= nsec;
}
/* Compute the time remaining to wait. tv_usec is certainly positive. */
result->tv_sec = x.tv_sec - y.tv_sec;
result->tv_usec = x.tv_usec - y.tv_usec;
/* Return 1 if result is negative. */
return x.tv_sec < y.tv_sec;
}
void build_pgm_header(PNM_Meta *ppm_meta, PNM_Meta *pgm_meta)
{
pgm_meta->width = ppm_meta->width;
pgm_meta->height = ppm_meta->height;
pgm_meta->colors = ppm_meta->colors;
pgm_meta->type = PNM_P5;
sprintf(pgm_meta->header, PGM_HEADER_FORMAT, pgm_meta->width, pgm_meta->height, pgm_meta->colors);
pgm_meta->header_length = strlen(pgm_meta->header);
}
void build_pbm_header(PNM_Meta *ppm_meta, PNM_Meta *pbm_meta)
{
pbm_meta->width = ppm_meta->width;
pbm_meta->height = ppm_meta->height;
pbm_meta->colors = ppm_meta->colors;
pbm_meta->type = PNM_P1;
sprintf(pbm_meta->header, PBM_HEADER_FORMAT, pbm_meta->width, pbm_meta->height);
pbm_meta->header_length = strlen(pbm_meta->header);
}
void create_pixel_array(PNM_Meta *pnm_meta, UINT8 **&data_out)
{
data_out = new UINT8* [pnm_meta->height];
for (int i = 0; i < pnm_meta->height; ++i) {
data_out[i] = new UINT8[pnm_meta->width];
}
}
void copy_pixel_array(PNM_Meta *pnm_meta, UINT8 **data_in, UINT8 **&data_out)
{
data_out = new UINT8* [pnm_meta->height];
for (int i = 0; i < pnm_meta->height; ++i) {
data_out[i] = new UINT8[pnm_meta->width];
for (int j = 0; j < pnm_meta->width; ++j) {
data_out[i][j] = data_in[i][j];
}
}
}
void delete_pixel_array(PNM_Meta *pnm_meta, UINT8 **&data)
{
for (int i = 0; i < pnm_meta->height; ++i) {
delete data[i];
}
delete data;
}
// Currently only saves in P1 one format since it is simpler.
// Expected data is 0 and 1 and not the ascii 0 (48) and 1 (49)
void write_pbm(char filename_out[], PNM_Meta *pbm_meta, UINT8 **data)
{
FILE *fpout;
int i;
int j;
int line_len;
int max_line_len = 69;
char newline = '\n';
UINT8 out;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)pbm_meta->header, pbm_meta->header_length, 1, fpout);
line_len = 0;
for (i = 0; i < pbm_meta->height; ++i) {
for (j = 0; j < pbm_meta->width; ++j) {
out = P1_WHITE + data[i][j];
fwrite((void *)&out, 1, 1, fpout);
++line_len;
if (line_len == max_line_len) {
fwrite((void *)&newline, 1, 1, fpout);
line_len = 0;
}
}
}
fclose(fpout);
}
void write_pgm(char filename_out[], PNM_Meta *pgm_meta, UINT8 **data_in)
{
FILE *fpout;
int i;
int j;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)pgm_meta->header, pgm_meta->header_length, 1, fpout);
for (i = 0; i < pgm_meta->height; ++i) {
for (j = 0; j < pgm_meta->width; ++j) {
fwrite((void *)&data_in[i][j], 1, 1, fpout);
}
}
fclose(fpout);
}
void write_ppm(char filename_out[], PNM_Meta *ppm_meta, UINT8 **r_data, UINT8 **g_data, UINT8 **b_data)
{
FILE *fpout;
int i;
int j;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)ppm_meta->header, ppm_meta->header_length, 1, fpout);
for (i = 0; i < ppm_meta->height; ++i) {
for (j = 0; j < ppm_meta->width; ++j) {
fwrite((void *)&r_data[i][j], 1, 1, fpout);
fwrite((void *)&g_data[i][j], 1, 1, fpout);
fwrite((void *)&b_data[i][j], 1, 1, fpout);
}
}
fclose(fpout);
}
void pbm_to_pgm(PNM_Meta *pbm_meta, UINT8 **data_pbm, UINT8 **&data_pgm)
{
int i;
int j;
int h = pbm_meta->height;
int w = pbm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if (data_pbm[i][j] == P4_BLACK) {
data_pgm[i][j] = BLACK;
} else {
data_pgm[i][j] = WHITE;
}
}
}
}
// Reads PNM file and returns header and image data as separate R, G, and B arrays.
// TODO(richard-to): Currently supports P6 format only.
bool read_ppm(char filename_in[], PNM_Meta *ppm_meta, UINT8 **&r_data, UINT8 **&g_data, UINT8 **&b_data)
{
FILE *fpin;
char image_type[3];
char image_width[5];
char image_height[5];
char image_colors[3];
std::stringstream sstr;
int sstr_val;
int i = 0;
int j = 0;
int h = 0;
char char_read;
int result = 0;
bool reading = true;
PNM_LexerMode mode = PNM_TYPE;
if ((fpin = fopen(filename_in, "r")) == NULL) {
LOG(("Error opening %s\n", filename_in));
return false;
}
while (reading) {
result = fread((void *)&char_read, 1, 1, fpin);
if (result == 0) {
LOG(("Error reading %s\n", filename_in));
reading = false;
break;
}
if (mode != PNM_COMMENT && char_read != PNM_LEX_BEGIN_COMMENT) {
ppm_meta->header[h++] = char_read;
}
if (mode == PNM_TYPE) {
if (char_read == PNM_LEX_DELIM) {
image_type[i] = '\0';
mode = PNM_WIDTH;
i = 0;
} else {
image_type[i] = char_read;
++i;
}
} else if (mode == PNM_WIDTH) {
if (char_read == PNM_LEX_BEGIN_HEIGHT) {
image_width[i] = '\0';
mode = PNM_HEIGHT;
i = 0;
} else if (char_read == PNM_LEX_BEGIN_COMMENT) {
mode = PNM_COMMENT;
i = 0;
} else {
image_width[i] = char_read;
++i;
}
} else if (mode == PNM_HEIGHT) {
if (char_read == PNM_LEX_DELIM) {
image_height[i] = '\0';
mode = PNM_COLORS;
i = 0;
} else {
image_height[i] = char_read;
++i;
}
} else if (mode == PNM_COLORS) {
if (char_read == PNM_LEX_DELIM) {
image_colors[i] = '\0';
reading = false;
} else {
image_colors[i] = char_read;
++i;
}
} else if (mode == PNM_COMMENT) {
if (char_read == PNM_LEX_DELIM) {
mode = PNM_WIDTH;
i = 0;
}
}
}
ppm_meta->header[h] = '\0';
ppm_meta->header_length = h;
ppm_meta->type = PNM_P6;
sstr.str(image_width);
sstr >> sstr_val;
ppm_meta->width = sstr_val;
sstr.clear();
sstr.str(image_height);
sstr >> sstr_val;
ppm_meta->height = sstr_val;
sstr.clear();
sstr.str(image_colors);
sstr >> sstr_val;
ppm_meta->colors = sstr_val;
r_data = new UINT8* [ppm_meta->height];
g_data = new UINT8* [ppm_meta->height];
b_data = new UINT8* [ppm_meta->height];
for (int i = 0; i < ppm_meta->height; ++i) {
r_data[i] = new UINT8[ppm_meta->width];
g_data[i] = new UINT8[ppm_meta->width];
b_data[i] = new UINT8[ppm_meta->width];
}
for (i = 0; i < ppm_meta->height; ++i) {
for (j = 0; j < ppm_meta->width; ++j) {
fread((void *)&r_data[i][j], 1, 1, fpin);
fread((void *)&g_data[i][j], 1, 1, fpin);
fread((void *)&b_data[i][j], 1, 1, fpin);
}
}
fclose(fpin);
return true;
}
void bg_subtraction(PNM_Meta *ppm_meta, int diff_thresh, UINT8 sub_color, UINT8 **data_in, UINT8 **data_bg, UINT8 **&data_diff)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if (abs((int)data_in[i][j] - (int)data_bg[i][j]) > diff_thresh) {
data_diff[i][j] = data_in[i][j];
} else {
data_diff[i][j] = sub_color;
}
}
}
}
void threshold(PNM_Meta *ppm_meta, int thresh, UINT8 white, UINT8 black, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if ((int)data_in[i][j] > thresh) {
data_out[i][j] = white;
} else {
data_out[i][j] = black;
}
}
}
}
void invert(PNM_Meta *ppm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
data_out[i][j] = WHITE - data_in[i][j];
}
}
}
void simple_skel(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p0 == 1 && chi == 2 && sigma != 1) {
data[i][j] = 0;
finished = false;
}
}
}
}
}
void simple_skel_2(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **marked_data;
create_pixel_array(pbm_meta, marked_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p0 == 1 && chi == 2 && sigma != 1) {
marked_data[i][j] = 1;
finished = false;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
if (marked_data[i][j] == 1) {
data[i][j] = 0;
}
}
}
}
delete_pixel_array(pbm_meta, marked_data);
}
void simple_skel_3(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **n_data;
UINT8 **s_data;
UINT8 **e_data;
UINT8 **w_data;
copy_pixel_array(pbm_meta, data, n_data);
copy_pixel_array(pbm_meta, data, s_data);
copy_pixel_array(pbm_meta, data, e_data);
copy_pixel_array(pbm_meta, data, w_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 0 && p0 == 1 && p7 == 1 && chi == 2 && sigma != 1) {
n_data[i][j] = 0;
finished = false;
} else {
n_data[i][j] = data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = n_data[i - 1][j - 1];
p3 = n_data[i - 1][j];
p2 = n_data[i - 1][j + 1];
p5 = n_data[i][j - 1];
p0 = n_data[i][j];
p1 = n_data[i][j + 1];
p6 = n_data[i + 1][j - 1];
p7 = n_data[i + 1][j];
p8 = n_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 1 && p0 == 1 && p7 == 0 && chi == 2 && sigma != 1) {
s_data[i][j] = 0;
finished = false;
} else {
s_data[i][j] = n_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = s_data[i - 1][j - 1];
p3 = s_data[i - 1][j];
p2 = s_data[i - 1][j + 1];
p5 = s_data[i][j - 1];
p0 = s_data[i][j];
p1 = s_data[i][j + 1];
p6 = s_data[i + 1][j - 1];
p7 = s_data[i + 1][j];
p8 = s_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 1 && p0 == 1 && p1 == 0 && chi == 2 && sigma != 1) {
e_data[i][j] = 0;
finished = false;
} else {
e_data[i][j] = s_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = e_data[i - 1][j - 1];
p3 = e_data[i - 1][j];
p2 = e_data[i - 1][j + 1];
p5 = e_data[i][j - 1];
p0 = e_data[i][j];
p1 = e_data[i][j + 1];
p6 = e_data[i + 1][j - 1];
p7 = e_data[i + 1][j];
p8 = e_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 0 && p0 == 1 && p1 == 1 && chi == 2 && sigma != 1) {
w_data[i][j] = 0;
finished = false;
} else {
w_data[i][j] = e_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data[i][j] = w_data[i][j];
}
}
}
delete_pixel_array(pbm_meta, n_data);
delete_pixel_array(pbm_meta, s_data);
delete_pixel_array(pbm_meta, e_data);
delete_pixel_array(pbm_meta, w_data);
}
void simple_object_labeller(PNM_Meta *pbm_meta, UINT8 **&data_in, UINT8 **&data_out)
{
int a;
int b;
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 1;
bool finished = false;
while (finished == false) {
finished = true;
for (a = 1; a < h; ++a) {
for (b = 1; b < w; ++b) {
if (data_in[a][b] == 1 && data_out[a][b] == 0) {
data_out[a][b] = N;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data_out[i - 1][j - 1];
p3 = data_out[i - 1][j];
p2 = data_out[i - 1][j + 1];
p5 = data_out[i][j - 1];
p0 = data_out[i][j];
p1 = data_out[i][j + 1];
p6 = data_out[i + 1][j - 1];
p7 = data_out[i + 1][j];
p8 = data_out[i + 1][j + 1];
if (data_in[i][j] == 1 && data_out[i][j] == 0 &&
(p1 == N || p2 == N || p3 == N || p4 == N ||
p5 == N || p6 == N || p7 == N || p8 == N)) {
data_out[i][j] = N;
finished = false;
}
}
}
if (finished == false) {
++N;
}
}
}
}
}
}
void simple_object_labeller_2(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int a;
int b;
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 0;
int min = 100;
int list[4] = {0, 0, 0, 0};
int coexist[80][80];
for (i = 0; i < 80; ++i) {
for (j = 0; j < 80; ++j) {
if (i == j) {
coexist[i][j] = i;
} else {
coexist[i][j] = 0;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = (int)data_out[i - 1][j - 1];
p3 = (int)data_out[i - 1][j];
p2 = (int)data_out[i - 1][j + 1];
p5 = (int)data_out[i][j - 1];
p0 = (int)data_out[i][j];
p1 = (int)data_out[i][j + 1];
p6 = (int)data_out[i + 1][j - 1];
p7 = (int)data_out[i + 1][j];
p8 = (int)data_out[i + 1][j + 1];
if (data_in[i][j] == 1) {
if (p2 == 0 && p3 == 0 && p4 == 0 && p5 == 0) {
++N;
data_out[i][j] = N;
} else {
min = 100;
list[0] = p2;
list[1] = p3;
list[2] = p4;
list[3] = p5;
for (k = 0; k < 4; ++k) {
if (list[k] > 0 && list[k] < min) {
min = list[k];
}
}
p0 = data_out[i][j] = min;
if (p0 < p2) {
coexist[p0][p2] = p0;
} else {
coexist[p0][p2] = p2;
}
if (p0 < p3) {
coexist[p0][p3] = p0;
} else {
coexist[p0][p3] = p3;
}
if (p0 < p4) {
coexist[p0][p4] = p0;
} else {
coexist[p0][p4] = p4;
}
if (p0 < p5) {
coexist[p0][p5] = p0;
} else {
coexist[p0][p5] = p5;
}
}
}
}
}
for (i = 0; i < 80; ++i) {
min = 100;
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (j = 0; j < 80; ++j) {
min = 100;
for (i = 0; i < 80; ++i) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (i = 0; i < 80; ++i) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (i = 0; i < 80; ++i) {
min = 100;
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
if (data_out[i][j] > 0) {
min = data_out[i][j];
for (k = 0; k < 80; ++k) {
if (coexist[min][k] > 0) {
data_out[i][j] = coexist[min][k];
break;
}
}
}
}
}
}
void simple_dist_label(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 0;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data_out[i][j] = data_in[i][j] * WHITE;
}
}
bool finished = false;
while (finished == false) {
finished = true;
for (i = 1; i < h - 1; ++i) {
for (j = 1; j < w - 1; ++j) {
p4 = (int)data_out[i - 1][j - 1];
p3 = (int)data_out[i - 1][j];
p2 = (int)data_out[i - 1][j + 1];
p5 = (int)data_out[i][j - 1];
p0 = (int)data_out[i][j];
p1 = (int)data_out[i][j + 1];
p6 = (int)data_out[i + 1][j - 1];
p7 = (int)data_out[i + 1][j];
p8 = (int)data_out[i + 1][j + 1];
if (data_out[i][j] == WHITE
&& (p1 == N || p2 == N || p3 == N || p4 == N ||
p5 == N || p6 == N || p7 == N || p8 == N)) {
data_out[i][j] = N + 1;
finished = false;
}
}
}
++N;
}
}
void simple_erode(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p0;
int list[] = {0, 0, 0, 0, 0, 0, 0, 0};
int max = 0;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
max = 0;
list[0] = (int)data_in[i - 1][j - 1];
list[1] = (int)data_in[i - 1][j];
list[2] = (int)data_in[i - 1][j + 1];
list[3] = (int)data_in[i][j - 1];
list[4] = (int)data_in[i][j + 1];
list[5] = (int)data_in[i + 1][j - 1];
list[6] = (int)data_in[i + 1][j];
list[7] = (int)data_in[i + 1][j + 1];
for (k = 0; k < 8; ++k) {
if (list[k] > max) {
max = list[k];
}
}
p0 = (int)data_in[i][j];
if (p0 > 0 && p0 >= max) {
data_out[i][j] = data_in[i][j];
} else {
data_out[i][j] = P4_WHITE;
}
}
}
}
void guided_skel(PNM_Meta *pbm_meta, UINT8 **guide, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **n_data;
UINT8 **s_data;
UINT8 **e_data;
UINT8 **w_data;
copy_pixel_array(pbm_meta, data, n_data);
copy_pixel_array(pbm_meta, data, s_data);
copy_pixel_array(pbm_meta, data, e_data);
copy_pixel_array(pbm_meta, data, w_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 0 && p0 == 1 && p7 == 1 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
n_data[i][j] = 0;
finished = false;
} else {
n_data[i][j] = data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = n_data[i - 1][j - 1];
p3 = n_data[i - 1][j];
p2 = n_data[i - 1][j + 1];
p5 = n_data[i][j - 1];
p0 = n_data[i][j];
p1 = n_data[i][j + 1];
p6 = n_data[i + 1][j - 1];
p7 = n_data[i + 1][j];
p8 = n_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 1 && p0 == 1 && p7 == 0 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
s_data[i][j] = 0;
finished = false;
} else {
s_data[i][j] = n_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = s_data[i - 1][j - 1];
p3 = s_data[i - 1][j];
p2 = s_data[i - 1][j + 1];
p5 = s_data[i][j - 1];
p0 = s_data[i][j];
p1 = s_data[i][j + 1];
p6 = s_data[i + 1][j - 1];
p7 = s_data[i + 1][j];
p8 = s_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 1 && p0 == 1 && p1 == 0 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
e_data[i][j] = 0;
finished = false;
} else {
e_data[i][j] = s_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = e_data[i - 1][j - 1];
p3 = e_data[i - 1][j];
p2 = e_data[i - 1][j + 1];
p5 = e_data[i][j - 1];
p0 = e_data[i][j];
p1 = e_data[i][j + 1];
p6 = e_data[i + 1][j - 1];
p7 = e_data[i + 1][j];
p8 = e_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 0 && p0 == 1 && p1 == 1 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
w_data[i][j] = 0;
finished = false;
} else {
w_data[i][j] = e_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data[i][j] = w_data[i][j];
}
}
}
delete_pixel_array(pbm_meta, n_data);
delete_pixel_array(pbm_meta, s_data);
delete_pixel_array(pbm_meta, e_data);
delete_pixel_array(pbm_meta, w_data);
}
bool run_job(char *input_folder, char *output_folder, int frame_count, PNM_Meta *pgm_meta, UINT8 **&bg_frame)
{
char filename_in[100];
char filename_out[100];
PNM_Meta ppm_meta_frame;
UINT8 **r_frame;
UINT8 **g_frame;
UINT8 **b_frame;
UINT8 **frame_diff;
UINT8 **labelled_data;
UINT8 **output_frame;
PNM_Meta pbm_meta;
UINT8 **binary_data;
UINT8 **eroded_data;
sprintf(filename_in, FILENAME_IN, input_folder, frame_count);
sprintf(filename_out, FILENAME_OUT, output_folder, frame_count);
gettimeofday(&start, NULL);
LOG(("--Reading frame %d...", frame_count));
if (read_ppm(filename_in, &ppm_meta_frame, r_frame, g_frame, b_frame) == false) {
return false;
}
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
if (pgm_meta->header_length == 0) {
copy_pixel_array(&ppm_meta_frame, g_frame, bg_frame);
build_pgm_header(&ppm_meta_frame, pgm_meta);
}
gettimeofday(&start, NULL);
LOG(("--BG subtraction frame %d...", frame_count));
create_pixel_array(&ppm_meta_frame, frame_diff);
bg_subtraction(&ppm_meta_frame, DIFF_THRESH, DIFF_COLOR, g_frame, bg_frame, frame_diff);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Threshold frame %d...", frame_count));
create_pixel_array(&ppm_meta_frame, binary_data);
threshold(&ppm_meta_frame, THRESHOLD, P4_WHITE, P4_BLACK, frame_diff, binary_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
build_pbm_header(&ppm_meta_frame, &pbm_meta);
gettimeofday(&start, NULL);
LOG(("--Distance labelling frame %d...", frame_count));
create_pixel_array(&ppm_meta_frame, labelled_data);
simple_dist_label(&pbm_meta, binary_data, labelled_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Eroding frame %d...", frame_count));
copy_pixel_array(&pbm_meta, binary_data, eroded_data);
simple_erode(&pbm_meta, labelled_data, eroded_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Skeletonize frame %d...", frame_count));
guided_skel(&pbm_meta, eroded_data, binary_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Converting pbm to pgm on frame %d...", frame_count));
create_pixel_array(&ppm_meta_frame, output_frame);
pbm_to_pgm(&pbm_meta, binary_data, output_frame);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing frame %d...", frame_count));
write_pgm(filename_out, pgm_meta, output_frame);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Clean up memory for frame %d...", frame_count));
delete_pixel_array(&ppm_meta_frame, r_frame);
delete_pixel_array(&ppm_meta_frame, g_frame);
delete_pixel_array(&ppm_meta_frame, b_frame);
delete_pixel_array(&ppm_meta_frame, frame_diff);
delete_pixel_array(&pbm_meta, labelled_data);
delete_pixel_array(&pbm_meta, output_frame);
delete_pixel_array(&pbm_meta, binary_data);
delete_pixel_array(&pbm_meta, eroded_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
return true;
}
int main(int argc, char *argv[])
{
if (argc < 3) {
printf("Usage: ex4 input_folder output_folder\n");
exit(-1);
}
setbuf(stdout, NULL);
PNM_Meta pgm_meta;
UINT8 **bg_frame;
bool has_frames = true;
int frame_count = 0;
struct stat sb;
if (stat(argv[2], &sb) != 0 || S_ISDIR(sb.st_mode) == false) {
mkdir(argv[2], 0755);
}
gettimeofday(&t_start, NULL);
while (has_frames == true) {
gettimeofday(&p_start, NULL);
LOG(("Processing frame %d...\n", frame_count + 1));
has_frames = run_job(argv[1], argv[2], ++frame_count, &pgm_meta, bg_frame);
gettimeofday(&p_end, NULL);
timeval_diff(&t_diff, p_end, p_start);
LOG(("Processing frame...DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
}
gettimeofday(&t_end, NULL);
timeval_diff(&t_diff, t_end, t_start);
printf("%d frames processed in %ld.%lds\n", frame_count, t_diff.tv_sec, t_diff.tv_usec);
delete_pixel_array(&pgm_meta, bg_frame);
}
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
#include <string.h>
// Begin - Settings
#define DEBUG 1
#define DIFF_THRESH 40
#define DIFF_COLOR 255
#define THRESHOLD 200
// End - Settings
/* Settings for Dark Test Images
#define DEBUG 1
#define DIFF_THRESH 40
#define DIFF_COLOR 255
#define THRESHOLD 200
*/
/* Settings for Light Test Images
#define DEBUG 1
#define DIFF_THRESH 30
#define DIFF_COLOR 255
#define THRESHOLD 200
*/
#if DEBUG
#define LOG(a) printf a
#else
#define LOG(a) (void)0
#endif
#define PGM_HEADER_FORMAT "P5\n%d %d\n%d\n"
#define PBM_HEADER_FORMAT "P1\n%d %d\n"
#define WHITE 255
#define BLACK 0
#define P4_WHITE 0
#define P4_BLACK 1
#define P1_WHITE 48
#define P1_BLACK 49
#define PNM_LEX_DELIM '\n'
#define PNM_LEX_BEGIN_HEIGHT ' '
#define PNM_LEX_BEGIN_COMMENT '#'
enum PNM_LexerMode { PNM_TYPE, PNM_COMMENT, PNM_WIDTH, PNM_HEIGHT, PNM_COLORS };
enum PNM_Type { PNM_P1, PNM_P5, PNM_P6 };
typedef double FLOAT;
typedef unsigned int UINT32;
typedef unsigned long long int UINT64;
typedef unsigned char UINT8;
typedef struct _PNM_Meta {
char header[21];
unsigned int header_length;
PNM_Type type;
int width;
int height;
int colors;
} PNM_Meta;
static struct timeval t_diff, t_start, t_end, p_start, p_end, start, end;
// From: http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html
int timeval_diff(timeval *result, timeval x, timeval y)
{
/* Perform the carry for the later subtraction by updating y. */
if (x.tv_usec < y.tv_usec) {
int nsec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
y.tv_usec -= 1000000 * nsec;
y.tv_sec += nsec;
}
if (x.tv_usec - y.tv_usec > 1000000) {
int nsec = (x.tv_usec - y.tv_usec) / 1000000;
y.tv_usec += 1000000 * nsec;
y.tv_sec -= nsec;
}
/* Compute the time remaining to wait. tv_usec is certainly positive. */
result->tv_sec = x.tv_sec - y.tv_sec;
result->tv_usec = x.tv_usec - y.tv_usec;
/* Return 1 if result is negative. */
return x.tv_sec < y.tv_sec;
}
void build_pgm_header(PNM_Meta *ppm_meta, PNM_Meta *pgm_meta)
{
pgm_meta->width = ppm_meta->width;
pgm_meta->height = ppm_meta->height;
pgm_meta->colors = ppm_meta->colors;
pgm_meta->type = PNM_P5;
sprintf(pgm_meta->header, PGM_HEADER_FORMAT, pgm_meta->width, pgm_meta->height, pgm_meta->colors);
pgm_meta->header_length = strlen(pgm_meta->header);
}
void build_pbm_header(PNM_Meta *ppm_meta, PNM_Meta *pbm_meta)
{
pbm_meta->width = ppm_meta->width;
pbm_meta->height = ppm_meta->height;
pbm_meta->colors = ppm_meta->colors;
pbm_meta->type = PNM_P1;
sprintf(pbm_meta->header, PBM_HEADER_FORMAT, pbm_meta->width, pbm_meta->height);
pbm_meta->header_length = strlen(pbm_meta->header);
}
void create_pixel_array(PNM_Meta *pnm_meta, UINT8 **&data_out)
{
data_out = new UINT8* [pnm_meta->height];
for (int i = 0; i < pnm_meta->height; ++i) {
data_out[i] = new UINT8[pnm_meta->width];
}
}
void copy_pixel_array(PNM_Meta *pnm_meta, UINT8 **data_in, UINT8 **&data_out)
{
data_out = new UINT8* [pnm_meta->height];
for (int i = 0; i < pnm_meta->height; ++i) {
data_out[i] = new UINT8[pnm_meta->width];
for (int j = 0; j < pnm_meta->width; ++j) {
data_out[i][j] = data_in[i][j];
}
}
}
void delete_pixel_array(PNM_Meta *pnm_meta, UINT8 **&data)
{
for (int i = 0; i < pnm_meta->height; ++i) {
delete data[i];
}
delete data;
}
// Currently only saves in P1 one format since it is simpler.
// Expected data is 0 and 1 and not the ascii 0 (48) and 1 (49)
void write_pbm(char filename_out[], PNM_Meta *pbm_meta, UINT8 **data)
{
FILE *fpout;
int i;
int j;
int line_len;
int max_line_len = 69;
char newline = '\n';
UINT8 out;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)pbm_meta->header, pbm_meta->header_length, 1, fpout);
line_len = 0;
for (i = 0; i < pbm_meta->height; ++i) {
for (j = 0; j < pbm_meta->width; ++j) {
out = P1_WHITE + data[i][j];
fwrite((void *)&out, 1, 1, fpout);
++line_len;
if (line_len == max_line_len) {
fwrite((void *)&newline, 1, 1, fpout);
line_len = 0;
}
}
}
fclose(fpout);
}
void write_pgm(char filename_out[], PNM_Meta *pgm_meta, UINT8 **data_in)
{
FILE *fpout;
int i;
int j;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)pgm_meta->header, pgm_meta->header_length, 1, fpout);
for (i = 0; i < pgm_meta->height; ++i) {
for (j = 0; j < pgm_meta->width; ++j) {
fwrite((void *)&data_in[i][j], 1, 1, fpout);
}
}
fclose(fpout);
}
void write_ppm(char filename_out[], PNM_Meta *ppm_meta, UINT8 **r_data, UINT8 **g_data, UINT8 **b_data)
{
FILE *fpout;
int i;
int j;
if ((fpout = fopen(filename_out, "w")) == NULL) {
LOG(("Error writing %s\n", filename_out));
}
fwrite((void *)ppm_meta->header, ppm_meta->header_length, 1, fpout);
for (i = 0; i < ppm_meta->height; ++i) {
for (j = 0; j < ppm_meta->width; ++j) {
fwrite((void *)&r_data[i][j], 1, 1, fpout);
fwrite((void *)&g_data[i][j], 1, 1, fpout);
fwrite((void *)&b_data[i][j], 1, 1, fpout);
}
}
fclose(fpout);
}
// Reads PNM file and returns header and image data as separate R, G, and B arrays.
// TODO(richard-to): Currently supports P6 format only.
void read_ppm(char filename_in[], PNM_Meta *ppm_meta, UINT8 **&r_data, UINT8 **&g_data, UINT8 **&b_data)
{
FILE *fpin;
char image_type[3];
char image_width[5];
char image_height[5];
char image_colors[3];
std::stringstream sstr;
int sstr_val;
int i = 0;
int j = 0;
int h = 0;
char char_read;
int result = 0;
bool reading = true;
PNM_LexerMode mode = PNM_TYPE;
if ((fpin = fopen(filename_in, "r")) == NULL) {
LOG(("Error opening %s\n", filename_in));
}
while (reading) {
result = fread((void *)&char_read, 1, 1, fpin);
if (result == 0) {
LOG(("Error reading %s\n", filename_in));
reading = false;
break;
}
if (mode != PNM_COMMENT && char_read != PNM_LEX_BEGIN_COMMENT) {
ppm_meta->header[h++] = char_read;
}
if (mode == PNM_TYPE) {
if (char_read == PNM_LEX_DELIM) {
image_type[i] = '\0';
mode = PNM_WIDTH;
i = 0;
} else {
image_type[i] = char_read;
++i;
}
} else if (mode == PNM_WIDTH) {
if (char_read == PNM_LEX_BEGIN_HEIGHT) {
image_width[i] = '\0';
mode = PNM_HEIGHT;
i = 0;
} else if (char_read == PNM_LEX_BEGIN_COMMENT) {
mode = PNM_COMMENT;
i = 0;
} else {
image_width[i] = char_read;
++i;
}
} else if (mode == PNM_HEIGHT) {
if (char_read == PNM_LEX_DELIM) {
image_height[i] = '\0';
mode = PNM_COLORS;
i = 0;
} else {
image_height[i] = char_read;
++i;
}
} else if (mode == PNM_COLORS) {
if (char_read == PNM_LEX_DELIM) {
image_colors[i] = '\0';
reading = false;
} else {
image_colors[i] = char_read;
++i;
}
} else if (mode == PNM_COMMENT) {
if (char_read == PNM_LEX_DELIM) {
mode = PNM_WIDTH;
i = 0;
}
}
}
ppm_meta->header[h] = '\0';
ppm_meta->header_length = h;
ppm_meta->type = PNM_P6;
sstr.str(image_width);
sstr >> sstr_val;
ppm_meta->width = sstr_val;
sstr.clear();
sstr.str(image_height);
sstr >> sstr_val;
ppm_meta->height = sstr_val;
sstr.clear();
sstr.str(image_colors);
sstr >> sstr_val;
ppm_meta->colors = sstr_val;
r_data = new UINT8* [ppm_meta->height];
g_data = new UINT8* [ppm_meta->height];
b_data = new UINT8* [ppm_meta->height];
for (int i = 0; i < ppm_meta->height; ++i) {
r_data[i] = new UINT8[ppm_meta->width];
g_data[i] = new UINT8[ppm_meta->width];
b_data[i] = new UINT8[ppm_meta->width];
}
for (i = 0; i < ppm_meta->height; ++i) {
for (j = 0; j < ppm_meta->width; ++j) {
fread((void *)&r_data[i][j], 1, 1, fpin);
fread((void *)&g_data[i][j], 1, 1, fpin);
fread((void *)&b_data[i][j], 1, 1, fpin);
}
}
fclose(fpin);
}
void bg_subtraction(PNM_Meta *ppm_meta, int diff_thresh, UINT8 sub_color, UINT8 **data_in, UINT8 **data_bg, UINT8 **&data_diff)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if (abs((int)data_in[i][j] - (int)data_bg[i][j]) > diff_thresh) {
data_diff[i][j] = data_in[i][j];
} else {
data_diff[i][j] = sub_color;
}
}
}
}
void threshold(PNM_Meta *ppm_meta, int thresh, UINT8 white, UINT8 black, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if ((int)data_in[i][j] > thresh) {
data_out[i][j] = white;
} else {
data_out[i][j] = black;
}
}
}
}
void invert(PNM_Meta *ppm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int h = ppm_meta->height;
int w = ppm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
data_out[i][j] = WHITE - data_in[i][j];
}
}
}
void simple_skel(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p0 == 1 && chi == 2 && sigma != 1) {
data[i][j] = 0;
finished = false;
}
}
}
}
}
void simple_skel_2(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **marked_data;
create_pixel_array(pbm_meta, marked_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p0 == 1 && chi == 2 && sigma != 1) {
marked_data[i][j] = 1;
finished = false;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
if (marked_data[i][j] == 1) {
data[i][j] = 0;
}
}
}
}
delete_pixel_array(pbm_meta, marked_data);
}
void simple_skel_3(PNM_Meta *pbm_meta, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **n_data;
UINT8 **s_data;
UINT8 **e_data;
UINT8 **w_data;
copy_pixel_array(pbm_meta, data, n_data);
copy_pixel_array(pbm_meta, data, s_data);
copy_pixel_array(pbm_meta, data, e_data);
copy_pixel_array(pbm_meta, data, w_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 0 && p0 == 1 && p7 == 1 && chi == 2 && sigma != 1) {
n_data[i][j] = 0;
finished = false;
} else {
n_data[i][j] = data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = n_data[i - 1][j - 1];
p3 = n_data[i - 1][j];
p2 = n_data[i - 1][j + 1];
p5 = n_data[i][j - 1];
p0 = n_data[i][j];
p1 = n_data[i][j + 1];
p6 = n_data[i + 1][j - 1];
p7 = n_data[i + 1][j];
p8 = n_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 1 && p0 == 1 && p7 == 0 && chi == 2 && sigma != 1) {
s_data[i][j] = 0;
finished = false;
} else {
s_data[i][j] = n_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = s_data[i - 1][j - 1];
p3 = s_data[i - 1][j];
p2 = s_data[i - 1][j + 1];
p5 = s_data[i][j - 1];
p0 = s_data[i][j];
p1 = s_data[i][j + 1];
p6 = s_data[i + 1][j - 1];
p7 = s_data[i + 1][j];
p8 = s_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 1 && p0 == 1 && p1 == 0 && chi == 2 && sigma != 1) {
e_data[i][j] = 0;
finished = false;
} else {
e_data[i][j] = s_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = e_data[i - 1][j - 1];
p3 = e_data[i - 1][j];
p2 = e_data[i - 1][j + 1];
p5 = e_data[i][j - 1];
p0 = e_data[i][j];
p1 = e_data[i][j + 1];
p6 = e_data[i + 1][j - 1];
p7 = e_data[i + 1][j];
p8 = e_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 0 && p0 == 1 && p1 == 1 && chi == 2 && sigma != 1) {
w_data[i][j] = 0;
finished = false;
} else {
w_data[i][j] = e_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data[i][j] = w_data[i][j];
}
}
}
delete_pixel_array(pbm_meta, n_data);
delete_pixel_array(pbm_meta, s_data);
delete_pixel_array(pbm_meta, e_data);
delete_pixel_array(pbm_meta, w_data);
}
void simple_object_labeller(PNM_Meta *pbm_meta, UINT8 **&data_in, UINT8 **&data_out)
{
int a;
int b;
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 1;
bool finished = false;
while (finished == false) {
finished = true;
for (a = 1; a < h; ++a) {
for (b = 1; b < w; ++b) {
if (data_in[a][b] == 1 && data_out[a][b] == 0) {
data_out[a][b] = N;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data_out[i - 1][j - 1];
p3 = data_out[i - 1][j];
p2 = data_out[i - 1][j + 1];
p5 = data_out[i][j - 1];
p0 = data_out[i][j];
p1 = data_out[i][j + 1];
p6 = data_out[i + 1][j - 1];
p7 = data_out[i + 1][j];
p8 = data_out[i + 1][j + 1];
if (data_in[i][j] == 1 && data_out[i][j] == 0 &&
(p1 == N || p2 == N || p3 == N || p4 == N ||
p5 == N || p6 == N || p7 == N || p8 == N)) {
data_out[i][j] = N;
finished = false;
}
}
}
if (finished == false) {
++N;
}
}
}
}
}
}
void simple_object_labeller_2(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int a;
int b;
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 0;
int min = 100;
int list[4] = {0, 0, 0, 0};
int coexist[80][80];
for (i = 0; i < 80; ++i) {
for (j = 0; j < 80; ++j) {
if (i == j) {
coexist[i][j] = i;
} else {
coexist[i][j] = 0;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = (int)data_out[i - 1][j - 1];
p3 = (int)data_out[i - 1][j];
p2 = (int)data_out[i - 1][j + 1];
p5 = (int)data_out[i][j - 1];
p0 = (int)data_out[i][j];
p1 = (int)data_out[i][j + 1];
p6 = (int)data_out[i + 1][j - 1];
p7 = (int)data_out[i + 1][j];
p8 = (int)data_out[i + 1][j + 1];
if (data_in[i][j] == 1) {
if (p2 == 0 && p3 == 0 && p4 == 0 && p5 == 0) {
++N;
data_out[i][j] = N;
} else {
min = 100;
list[0] = p2;
list[1] = p3;
list[2] = p4;
list[3] = p5;
for (k = 0; k < 4; ++k) {
if (list[k] > 0 && list[k] < min) {
min = list[k];
}
}
p0 = data_out[i][j] = min;
if (p0 < p2) {
coexist[p0][p2] = p0;
} else {
coexist[p0][p2] = p2;
}
if (p0 < p3) {
coexist[p0][p3] = p0;
} else {
coexist[p0][p3] = p3;
}
if (p0 < p4) {
coexist[p0][p4] = p0;
} else {
coexist[p0][p4] = p4;
}
if (p0 < p5) {
coexist[p0][p5] = p0;
} else {
coexist[p0][p5] = p5;
}
}
}
}
}
for (i = 0; i < 80; ++i) {
min = 100;
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (j = 0; j < 80; ++j) {
min = 100;
for (i = 0; i < 80; ++i) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (i = 0; i < 80; ++i) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (i = 0; i < 80; ++i) {
min = 100;
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0 && coexist[i][j] < min) {
min = coexist[i][j];
}
}
for (j = 0; j < 80; ++j) {
if (coexist[i][j] != 0) {
coexist[i][j] = min;
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
if (data_out[i][j] > 0) {
min = data_out[i][j];
for (k = 0; k < 80; ++k) {
if (coexist[min][k] > 0) {
data_out[i][j] = coexist[min][k];
break;
}
}
}
}
}
}
void simple_dist_label(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int N = 0;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data_out[i][j] = data_in[i][j] * WHITE;
}
}
bool finished = false;
while (finished == false) {
finished = true;
for (i = 1; i < h - 1; ++i) {
for (j = 1; j < w - 1; ++j) {
p4 = (int)data_out[i - 1][j - 1];
p3 = (int)data_out[i - 1][j];
p2 = (int)data_out[i - 1][j + 1];
p5 = (int)data_out[i][j - 1];
p0 = (int)data_out[i][j];
p1 = (int)data_out[i][j + 1];
p6 = (int)data_out[i + 1][j - 1];
p7 = (int)data_out[i + 1][j];
p8 = (int)data_out[i + 1][j + 1];
if (data_out[i][j] == WHITE
&& (p1 == N || p2 == N || p3 == N || p4 == N ||
p5 == N || p6 == N || p7 == N || p8 == N)) {
data_out[i][j] = N + 1;
finished = false;
}
}
}
++N;
}
}
void simple_erode(PNM_Meta *pbm_meta, UINT8 **data_in, UINT8 **&data_out)
{
int i;
int j;
int k;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p0;
int list[] = {0, 0, 0, 0, 0, 0, 0, 0};
int max = 0;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
max = 0;
list[0] = (int)data_in[i - 1][j - 1];
list[1] = (int)data_in[i - 1][j];
list[2] = (int)data_in[i - 1][j + 1];
list[3] = (int)data_in[i][j - 1];
list[4] = (int)data_in[i][j + 1];
list[5] = (int)data_in[i + 1][j - 1];
list[6] = (int)data_in[i + 1][j];
list[7] = (int)data_in[i + 1][j + 1];
for (k = 0; k < 8; ++k) {
if (list[k] > max) {
max = list[k];
}
}
p0 = (int)data_in[i][j];
if (p0 > 0 && p0 >= max) {
data_out[i][j] = P4_BLACK;
} else {
data_out[i][j] = P4_WHITE;
}
}
}
}
void guided_skel(PNM_Meta *pbm_meta, UINT8 **guide, UINT8 **&data)
{
int i;
int j;
int h = pbm_meta->height - 1;
int w = pbm_meta->width - 1;
int p4, p3, p2;
int p5, p0, p1;
int p6, p7, p8;
int sigma = 0;
int chi = 0;
bool finished = false;
UINT8 **n_data;
UINT8 **s_data;
UINT8 **e_data;
UINT8 **w_data;
copy_pixel_array(pbm_meta, data, n_data);
copy_pixel_array(pbm_meta, data, s_data);
copy_pixel_array(pbm_meta, data, e_data);
copy_pixel_array(pbm_meta, data, w_data);
while (finished == false) {
finished = true;
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = data[i - 1][j - 1];
p3 = data[i - 1][j];
p2 = data[i - 1][j + 1];
p5 = data[i][j - 1];
p0 = data[i][j];
p1 = data[i][j + 1];
p6 = data[i + 1][j - 1];
p7 = data[i + 1][j];
p8 = data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 0 && p0 == 1 && p7 == 1 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
n_data[i][j] = 0;
finished = false;
} else {
n_data[i][j] = data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = n_data[i - 1][j - 1];
p3 = n_data[i - 1][j];
p2 = n_data[i - 1][j + 1];
p5 = n_data[i][j - 1];
p0 = n_data[i][j];
p1 = n_data[i][j + 1];
p6 = n_data[i + 1][j - 1];
p7 = n_data[i + 1][j];
p8 = n_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p3 == 1 && p0 == 1 && p7 == 0 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
s_data[i][j] = 0;
finished = false;
} else {
s_data[i][j] = n_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = s_data[i - 1][j - 1];
p3 = s_data[i - 1][j];
p2 = s_data[i - 1][j + 1];
p5 = s_data[i][j - 1];
p0 = s_data[i][j];
p1 = s_data[i][j + 1];
p6 = s_data[i + 1][j - 1];
p7 = s_data[i + 1][j];
p8 = s_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 1 && p0 == 1 && p1 == 0 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
e_data[i][j] = 0;
finished = false;
} else {
e_data[i][j] = s_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
p4 = e_data[i - 1][j - 1];
p3 = e_data[i - 1][j];
p2 = e_data[i - 1][j + 1];
p5 = e_data[i][j - 1];
p0 = e_data[i][j];
p1 = e_data[i][j + 1];
p6 = e_data[i + 1][j - 1];
p7 = e_data[i + 1][j];
p8 = e_data[i + 1][j + 1];
sigma = p4 + p3 + p2 + p5 + p0 + p1 + p6 + p7 + p8;
chi = (int)(p1 != p3) + (int)(p3 != p5) + (int)(p5 != p7)
+ (int)(p7 != p1)
+ 2 * ((int)((p2 > p1) && (p2 > p3)) + (int)((p4 > p3) && (p4 > p5))
+ (int)((p6 > p5) && (p6 > p7)) + (int)((p8 > p7) && (p8 > p1)));
if (p5 == 0 && p0 == 1 && p1 == 1 && chi == 2 && sigma != 1 && guide[i][j] == 0) {
w_data[i][j] = 0;
finished = false;
} else {
w_data[i][j] = e_data[i][j];
}
}
}
for (i = 1; i < h; ++i) {
for (j = 1; j < w; ++j) {
data[i][j] = w_data[i][j];
}
}
}
delete_pixel_array(pbm_meta, n_data);
delete_pixel_array(pbm_meta, s_data);
delete_pixel_array(pbm_meta, e_data);
delete_pixel_array(pbm_meta, w_data);
}
void pbm_to_pgm(PNM_Meta *pbm_meta, UINT8 **data_pbm, UINT8 **&data_pgm)
{
int i;
int j;
int h = pbm_meta->height;
int w = pbm_meta->width;
for (i = 0; i < h; ++i) {
for (j = 0; j < w; ++j) {
if (data_pbm[i][j] == P4_BLACK) {
data_pgm[i][j] = BLACK;
} else {
data_pgm[i][j] = WHITE;
}
}
}
}
int main(int argc, char *argv[])
{
setbuf(stdout, NULL);
struct stat sb;
char filename_buffer[100];
PNM_Meta ppm_meta_frame;
UINT8 **r_frame;
UINT8 **g_frame;
UINT8 **b_frame;
PNM_Meta ppm_meta_bg;
UINT8 **r_bg;
UINT8 **g_bg;
UINT8 **b_bg;
PNM_Meta pgm_meta;
UINT8 **frame_diff;
UINT8 **labelled_data;
PNM_Meta pbm_meta;
UINT8 **binary_data;
UINT8 **eroded_data;
if (argc < 3) {
printf("Usage: ex4_1 image.ppm bg.ppm out_folder\n");
exit(-1);
}
if (stat(argv[3], &sb) != 0 || S_ISDIR(sb.st_mode) == false) {
mkdir(argv[3], 0755);
}
gettimeofday(&t_start, NULL);
printf("Applying skeletong algorithm to %s with background %s...\n\n", argv[1], argv[2]);
gettimeofday(&start, NULL);
LOG(("--Reading image %s...", argv[1]));
read_ppm(argv[1], &ppm_meta_frame, r_frame, g_frame, b_frame);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Reading background image %s...", argv[2]));
read_ppm(argv[2], &ppm_meta_bg, r_bg, g_bg, b_bg);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--BG subtraction diff on image..."));
create_pixel_array(&ppm_meta_frame, frame_diff);
bg_subtraction(&ppm_meta_frame, DIFF_THRESH, DIFF_COLOR, g_frame, g_bg, frame_diff);
build_pgm_header(&ppm_meta_frame, &pgm_meta);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing bgsub.pgm to output folder..."));
sprintf(filename_buffer, "%s/bgsub.pgm", argv[3]);
write_pgm(filename_buffer, &pgm_meta, frame_diff);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Thresholding image..."));
create_pixel_array(&ppm_meta_frame, binary_data);
threshold(&ppm_meta_frame, THRESHOLD, P4_WHITE, P4_BLACK, frame_diff, binary_data);
build_pbm_header(&ppm_meta_frame, &pbm_meta);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing threshold.pbm to output folder..."));
sprintf(filename_buffer, "%s/threshold.pbm", argv[3]);
write_pbm(filename_buffer, &pbm_meta, binary_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Distance labelling image..."));
create_pixel_array(&pgm_meta, labelled_data);
simple_dist_label(&pbm_meta, binary_data, labelled_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing distance_label.pgm to output folder..."));
sprintf(filename_buffer, "%s/distance_label.pgm", argv[3]);
write_pgm(filename_buffer, &pgm_meta, labelled_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Thinning image..."));
copy_pixel_array(&pbm_meta, binary_data, eroded_data);
simple_erode(&pbm_meta, labelled_data, eroded_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing eroded.pbm to output folder..."));
sprintf(filename_buffer, "%s/eroded.pbm", argv[3]);
write_pbm(filename_buffer, &pbm_meta, eroded_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Skeletonizing image..."));
guided_skel(&pbm_meta, eroded_data, binary_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Writing skel.pbm to output folder..."));
sprintf(filename_buffer, "%s/skel.pbm", argv[3]);
write_pbm(filename_buffer, &pbm_meta, binary_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&start, NULL);
LOG(("--Cleaning up memory..."));
delete_pixel_array(&ppm_meta_frame, r_frame);
delete_pixel_array(&ppm_meta_frame, g_frame);
delete_pixel_array(&ppm_meta_frame, b_frame);
delete_pixel_array(&ppm_meta_bg, r_bg);
delete_pixel_array(&ppm_meta_bg, g_bg);
delete_pixel_array(&ppm_meta_bg, b_bg);
delete_pixel_array(&ppm_meta_frame, frame_diff);
delete_pixel_array(&pbm_meta, labelled_data);
delete_pixel_array(&pbm_meta, binary_data);
delete_pixel_array(&pbm_meta, eroded_data);
gettimeofday(&end, NULL);
timeval_diff(&t_diff, end, start);
LOG(("DONE...%ld.%lds\n\n", t_diff.tv_sec, t_diff.tv_usec));
gettimeofday(&t_end, NULL);
timeval_diff(&t_diff, t_end, t_start);
printf("Skeleton algorithm completed in %ld.%lds\n", t_diff.tv_sec, t_diff.tv_usec);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment