-
Notifications
You must be signed in to change notification settings - Fork 0
/
Farm.cpp
executable file
·174 lines (150 loc) · 4.91 KB
/
Farm.cpp
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
#include "CImg.h"
#include<iostream>
#include <stdlib.h>
#include <chrono>
#include <thread>
#include <vector>
#include <assert.h>
#include <vector>
#include <iostream>
#include <ff/farm.hpp>
#include <ff/node.hpp>
using namespace cimg_library;
using namespace ff;
struct Task_t {
Task_t(CImg<float> imgin, int save_flag, float threshold):imgin(imgin),save_flag(save_flag),threshold(threshold) {}
CImg<float> imgin;
int save_flag;
float threshold;
};
CImg<float> RGBtoGrayScale(CImg<float> in)
{
// Creat a grayImage as the size of input image
CImg<float> grayImage(in.width(),in.height(),1,1,0);
// Translate to weighted gray image
for(int i=0;i<in.width();i++)
for(int j=0;j<in.height();j++)
grayImage(i,j,0) = (float)(0.299*in(i,j,0) + 0.587*in(i,j,1) + 0.114*in(i,j,2));
// Because our eyes are more sensible to light from the green frequencies.
return grayImage;
}
void Histogram(CImg<float> in, int* histogram)
{
// initialize all intensity values to 0
for(int i = 0; i < 256; i++)
histogram[i] = 0;
// histogram
for(int i=0;i<in.width();i++)
for(int j=0;j<in.height();j++)
histogram[(int)in(i,j,0)]++;
}
void Thresholding(CImg<float> &in, float p, int* histogram)
{
int nPixelsBrighter[256];
// initialize all intensity values to 0
for(int i = 0; i < 256; i++)
nPixelsBrighter[i] = 0;
// get the number of Pixels Brighter
for(int v = 0; v < 256; v++)
for(int u = v+1; u < 256; u++)
nPixelsBrighter[v] += histogram[u];
// Thresholding
for(int i=0;i<in.width();i++)
for(int j=0;j<in.height();j++)
{
int tNumPixels = in.width()*in.height();
//int curNum = histogram[(int)in(i,j,0)];
float percentage = (float)nPixelsBrighter[(int)in(i,j,0)]/tNumPixels;
//std::cout<<"nPixelsBrighter= "<< nPixelsBrighter[(int)in(i,j,0)]<<" curNum="<< curNum<<" percentage="<<percentage<<std::endl;
if(percentage <= p)
in(i,j,0) = 255;// 255:white
else
in(i,j,0) = 0;// 0:black
}
}
void HistogramThresolding(CImg<float> imgin, int save_flag, float threshold)
{
//std::cout << save_flag <<" HistogramThresolding : " << std::this_thread::get_id() <<std::endl;
CImg<float> imgout(imgin.width(),imgin.height(),1,1,0);
// RGBtoGrayScale
imgout = RGBtoGrayScale(imgin);
// Histogram
int histogram[256];// allcoate memory for no of pixels for each intensity value
Histogram(imgout, histogram);
// Thresholding
Thresholding(imgout, threshold, histogram);
// Save image
if(save_flag == 0)
{
//std::cout << "Save image: " << std::this_thread::get_id() << std::endl;
imgout.save("outputImage.jpg");
}
}
struct Emitter: ff_node_t<Task_t> {
CImg<float> imgin;
size_t nImages;
int save_flag;
float threshold;
Emitter(CImg<float> imgin, size_t nImages, int save_flag, float threshold)
:imgin(imgin),nImages(nImages),save_flag(save_flag),threshold(threshold) {}
Task_t *svc(Task_t *in) {
while (true) {
if(nImages)
{
if(save_flag)
{
Task_t *task = new Task_t(imgin, save_flag, threshold);
ff_send_out(task);
}
else
{
Task_t *task = new Task_t(imgin, save_flag, threshold);
ff_send_out(task);
save_flag = 1;
}
nImages--;
}else{ break;}
}
return EOS;
}
};
struct Worker: ff_node_t<Task_t> {
Task_t * svc(Task_t *in) {
HistogramThresolding(in->imgin,in->save_flag,in->threshold);
return GO_ON;
}
};
int main(int argc, char * argv[])
{
//std::cout << "input :" << argv[0] << " " << argv[1] << " " << argv[2] << " " << argv[3] << std::endl;
if(argc < 4)
{
std::cerr << "use: "<< argv[0] << " nimages nworkers threshold"<<std::endl;
return -1;
}
size_t nImages = std::stoll(argv[1]);
size_t nworkers = std::stoll(argv[2]);
float threshold = atof(argv[3]);
assert(nImages >= nworkers);
int save_flag=0;
ffTime(START_TIME);
// read the image
CImg<float> imgin("inputImage.jpg");
ff_Farm<> farm([nworkers]() {
std::vector<std::unique_ptr<ff_node> > Works;
for(size_t i=0;i<nworkers;++i)
Works.push_back(make_unique<Worker>());
return Works;
} () ); // by default it has both an emitter and a collector
Emitter E(imgin, nImages ,save_flag, threshold);
farm.add_emitter(E); // replacing the default emitter
farm.remove_collector(); // removing the default collector
farm.set_scheduling_ondemand(); // set on-demand scheduling policy
if (farm.run_and_wait_end()<0) {
error("runtime error, exiting!\n");
return -1;
}
ffTime(STOP_TIME);
std::cout << "nworkers: " << nworkers << " ; " <<"Time: " << ffTime(GET_TIME) << " (ms)" <<std::endl;
return 0;
}