-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathsobel-cpu.cpp
More file actions
185 lines (172 loc) · 6.04 KB
/
sobel-cpu.cpp
File metadata and controls
185 lines (172 loc) · 6.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <vector>
#include <cmath>
#include <ctime>
using namespace std;
#pragma pack(1)
typedef struct {
char id[2];
int file_size;
int reserved;
int offset;
} header_type;
#pragma pack(1)
typedef struct {
int header_size;
int width;
int height;
unsigned short int color_planes;
unsigned short int color_depth;
unsigned int compression;
int image_size;
int xresolution;
int yresolution;
int num_colors;
int num_important_colors;
} information_type;
void sobel(int *l_source_array, int *l_result_array, int rows, int column_size,
int row, int col) {
int x_0, x_1, x_2, x_3, x_5, x_6, x_7, x_8, sum_0, sum_1, sum;
bool top = (row == 0);
bool bottom = (row == (rows - 1));
bool left_edge = (col == 0);
bool right_edge = (col == (column_size - 1));
if (top == false && bottom == false && left_edge == false &&
right_edge == false) {
x_0 = l_source_array[(row - 1) * column_size + (col - 1)];
x_1 = l_source_array[(row - 1) * column_size + (col)];
x_2 = l_source_array[(row - 1) * column_size + (col + 1)];
x_3 = l_source_array[(row)*column_size + (col - 1)];
x_5 = l_source_array[(row)*column_size + (col + 1)];
x_6 = l_source_array[(row + 1) * column_size + (col - 1)];
x_7 = l_source_array[(row + 1) * column_size + (col)];
x_8 = l_source_array[(row + 1) * column_size + (col + 1)];
sum_0 = (x_0 + (2 * x_1) + x_2) - (x_6 + (2 * x_7) + x_8);
sum_1 = (x_2 + (2 * x_5) + x_8) - (x_0 + (2 * x_3) + x_6);
sum = sum_0 + sum_1;
if (sum > 20) {
sum = 255;
} else {
sum = 0;
}
// write new data onto smaller matrix
l_result_array[((row - 1) * (column_size - 2)) + (col - 1)] = sum;
}
}
int main(int argc, char *argv[]) {
header_type header;
information_type information;
string imageFileName, newImageFileName;
unsigned char tempData[3];
int row, col, row_bytes, padding;
// prepare files
imageFileName = argv[1];
ifstream imageFile;
imageFile.open(imageFileName.c_str(), ios::binary);
if (!imageFile) {
std::cerr << "file not found" << std::endl;
exit(-1);
}
// std::cout << "New imagefile name? ";
newImageFileName = argv[2];
ofstream newImageFile;
newImageFile.open(newImageFileName.c_str(), ios::binary);
// read file header
imageFile.read((char *)&header, sizeof(header_type));
if (header.id[0] != 'B' || header.id[1] != 'M') {
cerr << "Does not appear to be a .bmp file. Goodbye." << endl;
exit(-1);
}
// read/compute image information
imageFile.read((char *)&information, sizeof(information_type));
row_bytes = information.width * 3;
padding = row_bytes % 4;
if (padding)
padding = 4 - padding;
// extract image data, initialize vectors
int src_rows = information.height + 2;
int src_column_size = information.width + 2;
int src_size = src_rows * src_column_size;
int **data = (int **)malloc(src_size * sizeof(int *));
for (row = 1; row <= information.height; row++) {
data[row] = (int *)malloc(src_column_size * sizeof(int));
for (col = 0; col <= information.width; col++) {
if (col == 0) {
data[row][0] = 0;
} else {
imageFile.read((char *)tempData, 3 * sizeof(unsigned char));
data[row][col] = ((int)tempData[0]);
}
}
// pad last column
data[row][col + 1] = 0;
if (padding)
imageFile.read((char *)tempData, padding * sizeof(unsigned char));
}
// pad first & last row
int last_row = src_rows - 1;
data[0] = (int *)malloc(src_column_size * sizeof(int));
data[last_row] = (int *)malloc(src_column_size * sizeof(int));
for (col = 0; col < src_column_size; col++) {
data[0][col] = 0;
data[src_rows - 1][col] = 0;
}
std::cout << imageFileName << ": " << information.width << " x "
<< information.height << std::endl;
// linear-ize source array
int dest_size = information.width * information.height;
int *l_source_array = 0;
l_source_array = new int[src_size];
for (row = 0; row < src_rows; row++) {
for (col = 0; col < src_column_size; col++) {
l_source_array[row * src_column_size + col] = data[row][col];
}
}
int result_rows = information.height;
int result_column_size = information.width;
int *l_result_array = 0;
l_result_array = new int[dest_size];
clock_t cpu_start = clock();
for (row = 1; row < (information.height + 1); row++) {
for (col = 1; col < (information.width + 1); col++) {
sobel(l_source_array, l_result_array, src_rows, src_column_size, row,
col);
}
}
clock_t cpu_stop = clock();
double elapsed_cpu = double(cpu_stop - cpu_start) / (CLOCKS_PER_SEC / 1000);
std::cout << "CPU Time Taken (msec): " << elapsed_cpu << std::endl;
// de-linearize result array
int **newData = (int **)malloc(dest_size * sizeof(int *));
for (row = 0; row < result_rows; row++) {
newData[row] = new int[result_column_size];
for (col = 0; col < result_column_size; col++) {
newData[row][col] = l_result_array[(row * result_column_size) + col];
}
}
// write header to new image file
newImageFile.write((char *)&header, sizeof(header_type));
newImageFile.write((char *)&information, sizeof(information_type));
// write new image data to new image file
for (row = 0; row < information.height; row++) {
for (col = 0; col < information.width; col++) {
tempData[0] = (unsigned char)newData[row][col];
tempData[1] = (unsigned char)newData[row][col];
tempData[2] = (unsigned char)newData[row][col];
newImageFile.write((char *)tempData, 3 * sizeof(unsigned char));
}
if (padding) {
tempData[0] = 0;
tempData[1] = 0;
tempData[2] = 0;
newImageFile.write((char *)tempData, padding * sizeof(unsigned char));
}
}
std::cout << newImageFileName << " done." << std::endl;
imageFile.close();
newImageFile.close();
return 0;
}