Skip to content

Commit 331b9a6

Browse files
authored
Merge pull request #7 from ErickOF/feature-filter_module
Feature filter module
2 parents dd7151f + 26fe694 commit 331b9a6

File tree

7 files changed

+240
-29
lines changed

7 files changed

+240
-29
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,9 @@ tools/datagen/src/imgs/*_sobel_*
227227
# Ignore VCD files
228228
*.vcd
229229
test
230+
231+
# Ignore output images
232+
modules/filter/*.bitmap
233+
modules/filter/*.gif
234+
modules/filter/*.jpg
235+
modules/filter/*.png

modules/filter/Makefile

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Adding stb lib for image handling
2-
INCDIR_STB=lib/stb
3-
INCLUDES_STB := $(wildcard $(INCDIR_STB)/*.h)
2+
CFLAGS_OPENCV := $(shell pkg-config --cflags opencv4)
3+
LFLAGS_OPENCV := $(shell pkg-config --libs opencv4)
44

55
# Include common Makefile
66
include ../Makefile
77

88
# Include stb lib for compilation
9-
INCLUDES += INCLUDES_STB
9+
CFLAGS += $(CFLAGS_OPENCV)
10+
LFLAGS += $(LFLAGS_OPENCV)
1011

1112
# Defining preprocessor directive for debug
1213
ifdef IPS_DEBUG_EN
@@ -20,18 +21,21 @@ ifdef IPS_DUMP_EN
2021
LFLAGS += -DIPS_DUMP_EN
2122
endif # IPS_DUMP_EN
2223

23-
24-
# Defining preprocessor directive for test mode one wildcard normal
24+
# Defining preprocessor directive for test modes
25+
ifdef TEST_MODE_IMAGE
26+
CFLAGS += -DTEST_MODE_IMAGE
27+
LFLAGS += -DTEST_MODE_IMAGE
28+
else
29+
ifdef TEST_MODE_ONE_WINDOW_RANDOM
30+
CFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
31+
LFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
32+
else
2533
ifdef TEST_MODE_ONE_WINDOW_NORMAL
2634
CFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_NORMAL
2735
LFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_NORMAL
2836
endif # TEST_MODE_ONE_WINDOW_NORMAL
29-
30-
# Defining preprocessor directive for test mode one window random
31-
ifdef TEST_MODE_ONE_WINDOW_RANDOM
32-
CFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
33-
LFLAGS += -DTEST_MODE_ONE_WINDOW -DTEST_MODE_ONE_WINDOW_RANDOM
3437
endif # TEST_MODE_ONE_WINDOW_RANDOM
38+
endif # TEST_MODE_IMAGE
3539

3640
# Defining preprocessor directive for model - by default PV model
3741
ifdef IPS_FILTER_LT_EN

modules/filter/include/ips_filter_at_model.hpp

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -98,26 +98,11 @@ void Filter<IN, OUT, N>::exec_filter()
9898
// Getting the image window to filter
9999
IN* img_window_tmp = this->img_window.read();
100100

101-
#ifdef IPS_DEBUG_EN
102-
std::cout << "Performing convolution" << std::endl;
103-
#endif // IPS_DEBUG_EN
104-
105101
// Perform the convolution
106102
for (i = 0; i < N; ++i)
107103
for (j = 0; j < N; ++j)
108-
{
109-
#ifdef IPS_DEBUG_EN
110-
std::cout << "Starting [" << i << "][" << j << "]" << std::endl;
111-
#endif // IPS_DEBUG_EN
112104
result_tmp += this->kernel[i * N + j] * ((OUT) img_window_tmp[i * N + j]);
113-
#ifdef IPS_DEBUG_EN
114-
std::cout << "Done [" << i << "][" << j << "]" << std::endl;
115-
#endif // IPS_DEBUG_EN
116-
}
117105

118-
#ifdef IPS_DEBUG_EN
119-
std::cout << "Convolution result is done" << std::endl;
120-
#endif // IPS_DEBUG_EN
121106
this->result.write(result_tmp);
122107
}
123108
}
@@ -166,6 +151,21 @@ void Filter<IN, OUT, N>::init()
166151

167152
std::cout << std::endl;
168153
}
154+
#else
155+
#ifdef IPS_DUMP_EN
156+
size_t i, j;
157+
158+
for (i = 0; i < N; ++i)
159+
{
160+
for (j = 0; j < N; ++j)
161+
{
162+
// Adding the signals to the waveform
163+
std::ostringstream var_name;
164+
var_name << "kernel_" << i << "_" << j;
165+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
166+
}
167+
}
168+
#endif // IPS_DUMP_EN
169169
#endif // IPS_DEBUG_EN
170170
}
171171
#endif // IPS_FILTER_AT_MODEL_HPP

modules/filter/include/ips_filter_lt_model.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,21 @@ void Filter<IN, OUT, N>::init()
156156

157157
std::cout << std::endl;
158158
}
159+
#else
160+
#ifdef IPS_DUMP_EN
161+
size_t i, j;
162+
163+
for (i = 0; i < N; ++i)
164+
{
165+
for (j = 0; j < N; ++j)
166+
{
167+
// Adding the signals to the waveform
168+
std::ostringstream var_name;
169+
var_name << "kernel_" << i << "_" << j;
170+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
171+
}
172+
}
173+
#endif // IPS_DUMP_EN
159174
#endif // IPS_DEBUG_EN
160175
}
161176
#endif // IPS_FILTER_LT_MODEL_HPP

modules/filter/include/ips_filter_pv_model.hpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ void Filter<IN, OUT, N>::init_kernel()
112112

113113
std::cout << std::endl;
114114
}
115+
#else
116+
#ifdef IPS_DUMP_EN
117+
size_t i, j;
118+
119+
for (i = 0; i < N; ++i)
120+
{
121+
for (j = 0; j < N; ++j)
122+
{
123+
// Adding the signals to the waveform
124+
std::ostringstream var_name;
125+
var_name << "kernel_" << i << "_" << j;
126+
sc_trace(this->wf, this->kernel[i * N + j], var_name.str());
127+
}
128+
}
129+
#endif // IPS_DUMP_EN
115130
#endif // IPS_DEBUG_EN
116131
}
117132
#endif // IPS_FILTER_PV_MODEL_HPP

modules/filter/src/tb_filter.cpp

Lines changed: 175 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,22 @@
1+
#define int64 systemc_int64
2+
#define uint64 systemc_uint64
3+
#include <systemc.h>
14
#ifdef TEST_MODE_ONE_WINDOW_RANDOM
25
#include <cstdlib>
3-
#endif // TEST_MODE_ONE_WINDOW_RANDOM
6+
#elif defined(TEST_MODE_IMAGE)
7+
#include <cstdlib>
8+
#undef int64
9+
#undef uint64
10+
#define int64 opencv_int64
11+
#define uint64 opencv_uint64
12+
#include <opencv2/opencv.hpp>
13+
#undef int64
14+
#undef uint64
15+
#define SYSTEMC_TYPES_ALREADY_DEFINED
16+
#endif // TEST_MODE
417
#ifdef IPS_DUMP_EN
518
#include <sstream>
619
#endif // IPS_DUMP_EN
7-
#include <systemc.h>
820

921
#ifndef IPS_FILTER_KERNEL_SIZE
1022
#define IPS_FILTER_KERNEL_SIZE 3
@@ -15,6 +27,9 @@
1527
#ifndef IPS_OUT_TYPE_TB
1628
#define IPS_OUT_TYPE_TB float
1729
#endif // IPS_OUT_TYPE_TB
30+
#ifndef IPS_IMG_PATH_TB
31+
#define IPS_IMG_PATH_TB "../../tools/datagen/src/imgs/car_noisy_image.png"
32+
#endif // IPS_IMG_PATH_TB
1833

1934
#ifndef IPS_FILTER_PV_EN
2035
// N * N * copy_pixel_to_mem_time + mult + redux + copy_pixel_to_mem_time
@@ -33,6 +48,152 @@
3348
#endif // IPS_FILTER_XX_EN
3449

3550

51+
#ifdef TEST_MODE_IMAGE
52+
#ifdef IPS_DUMP_EN
53+
void run_image(sc_trace_file* wf)
54+
#else
55+
void run_image()
56+
#endif // IPS_DUMP_EN
57+
{
58+
#ifdef IPS_DEBUG_EN
59+
SC_REPORT_INFO("TEST_MODE_IMAGE", "Running test");
60+
#endif // IPS_DEBUG_EN
61+
62+
const std::string img_path = IPS_IMG_PATH_TB;
63+
cv::Mat read_image = cv::imread(img_path, cv::IMREAD_GRAYSCALE);
64+
cv::Mat image;
65+
read_image.convertTo(image, CV_32F);
66+
67+
cv::Mat o_img(image.size(), image.type());
68+
69+
#ifdef IPS_DUMP_EN
70+
std::cout << "Loading image: " << img_path << std::endl;
71+
#endif // IPS_DUMP_EN
72+
73+
// Check if the image is loaded successfully
74+
if (image.empty())
75+
{
76+
std::cerr << "Error: Could not open or find the image!" << std::endl;
77+
exit(EXIT_FAILURE);
78+
}
79+
80+
#ifdef IPS_DUMP_EN
81+
std::cout << "Image info: ";
82+
std::cout << "rows = " << image.rows;
83+
std::cout << " cols = " << image.cols;
84+
std::cout << " channels = " << image.channels() << std::endl;
85+
#endif // IPS_DUMP_EN
86+
87+
// Variables
88+
IPS_IN_TYPE_TB* img_window;
89+
IPS_OUT_TYPE_TB result;
90+
91+
int i, j;
92+
int x, y;
93+
94+
#ifdef IPS_FILTER_AT_EN
95+
sc_signal<IPS_IN_TYPE_TB*> s_img_window;
96+
sc_signal<IPS_OUT_TYPE_TB> s_result;
97+
#endif // IPS_FILTER_AT_EN
98+
99+
// Initialize image window
100+
img_window = new IPS_IN_TYPE_TB[IPS_FILTER_KERNEL_SIZE * IPS_FILTER_KERNEL_SIZE];
101+
102+
// Instantiate filter module and do the connection
103+
#ifdef IPS_DUMP_EN
104+
for (i = 0; i < IPS_FILTER_KERNEL_SIZE; ++i)
105+
{
106+
for (j = 0; j < IPS_FILTER_KERNEL_SIZE; ++j)
107+
{
108+
std::ostringstream var_name;
109+
var_name << "img_window_" << i << "_" << j;
110+
sc_trace(wf, img_window[i * IPS_FILTER_KERNEL_SIZE + j], var_name.str());
111+
}
112+
}
113+
114+
Filter<IPS_IN_TYPE_TB, IPS_OUT_TYPE_TB, IPS_FILTER_KERNEL_SIZE> filter("filter", wf);
115+
sc_trace(wf, result, "result");
116+
#else
117+
Filter<IPS_IN_TYPE_TB, IPS_OUT_TYPE_TB, IPS_FILTER_KERNEL_SIZE> filter("filter");
118+
#endif // IPS_DUMP_EN
119+
#ifdef IPS_FILTER_AT_EN
120+
filter.img_window(s_img_window);
121+
filter.result(s_result);
122+
#endif // IPS_FILTER_AT_EN
123+
124+
sc_start();
125+
126+
#ifdef IPS_DEBUG_EN
127+
std::cout << "Test starting" << std::endl;
128+
std::cout << "@" << sc_time_stamp() << std::endl;
129+
#endif // IPS_DEBUG_EN
130+
131+
// Create each window
132+
for (y = 0; y < image.rows - IPS_FILTER_KERNEL_SIZE; ++y)
133+
{
134+
for (x = 0; x < image.cols - IPS_FILTER_KERNEL_SIZE; ++x)
135+
{
136+
#ifdef IPS_DEBUG_EN
137+
SC_REPORT_INFO("TEST_MODE_IMAGE", "filtering");
138+
#endif // IPS_DEBUG_EN
139+
140+
// Define the ROI
141+
cv::Rect roi(x, y, IPS_FILTER_KERNEL_SIZE, IPS_FILTER_KERNEL_SIZE);
142+
cv::Mat sub_img = image(roi);
143+
144+
for (i = 0; i < IPS_FILTER_KERNEL_SIZE; ++i)
145+
{
146+
for (j = 0; j < IPS_FILTER_KERNEL_SIZE; ++j)
147+
{
148+
img_window[i * IPS_FILTER_KERNEL_SIZE + j] = sub_img.at<IPS_IN_TYPE_TB>(i, j);
149+
#ifdef IPS_DEBUG_EN
150+
std::cout << "[" << img_window[i * IPS_FILTER_KERNEL_SIZE + j] << "]";
151+
#endif // IPS_DEBUG_EN
152+
}
153+
154+
#ifdef IPS_DEBUG_EN
155+
std::cout << std::endl;
156+
#endif // IPS_DEBUG_EN
157+
}
158+
159+
// Apply convolution
160+
#ifdef IPS_FILTER_PV_EN
161+
filter.filter(img_window, result);
162+
#elif defined(IPS_FILTER_LT_EN)
163+
filter.filter(img_window, &result);
164+
sc_start(DELAY_TIME + 10, SC_NS);
165+
#elif defined(IPS_FILTER_AT_EN)
166+
s_img_window.write(img_window);
167+
filter.filter();
168+
sc_start(DELAY_TIME + 10, SC_NS);
169+
170+
result = s_result.read();
171+
#endif // IPS_FILTER_XX_EN
172+
173+
o_img.at<IPS_OUT_TYPE_TB>(y, x) = result;
174+
175+
#ifdef IPS_DEBUG_EN
176+
std::cout << "Result[" << x << "][" << y << "] = " << o_img.at<IPS_OUT_TYPE_TB>(y, x) << std::endl << std::endl;
177+
#endif // IPS_DEBUG_EN
178+
}
179+
}
180+
181+
#ifdef IPS_DUMP_EN
182+
sc_start(1, SC_NS);
183+
#endif // IPS_DUMP_EN
184+
185+
// Convert the floating-point image to 8-bit unsigned integer for saving
186+
cv::Mat final_img;
187+
o_img.convertTo(final_img, CV_8U, 1.0);
188+
189+
// Save the final image
190+
std::string output_img_path = "filtered_image.png";
191+
cv::imwrite(output_img_path, final_img);
192+
193+
delete [] img_window;
194+
}
195+
#endif // TEST_MODE_IMAGE
196+
36197
#ifdef TEST_MODE_ONE_WINDOW
37198
#ifdef IPS_DUMP_EN
38199
void run_one_window(sc_trace_file* wf)
@@ -52,7 +213,7 @@ void run_one_window()
52213
#endif
53214

54215
// Variables
55-
IPS_IN_TYPE_TB *img_window;
216+
IPS_IN_TYPE_TB* img_window;
56217
IPS_OUT_TYPE_TB result;
57218

58219
#ifdef IPS_FILTER_AT_EN
@@ -155,8 +316,18 @@ int sc_main(int, char*[])
155316
#endif // IPS_DUMP_EN
156317

157318
#ifdef TEST_MODE_ONE_WINDOW
319+
#ifdef IPS_DUMP_EN
158320
run_one_window(wf);
159-
#endif // TEST_MODE_ONE_WINDOW
321+
#else
322+
run_one_window();
323+
#endif // IPS_DUMP_EN
324+
#elif defined(TEST_MODE_IMAGE)
325+
#ifdef IPS_DUMP_EN
326+
run_image(wf);
327+
#else
328+
run_image();
329+
#endif // IPS_DUMP_EN
330+
#endif // TEST_MODE
160331

161332
#ifdef IPS_DUMP_EN
162333
std::cout << "@" << sc_time_stamp() << " Terminating simulation" << std::endl;

tools/datagen/src/imgs/car.png

489 KB
Loading

0 commit comments

Comments
 (0)