-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathimage.cpp
139 lines (126 loc) · 3.71 KB
/
image.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
/**
* @file image.cpp
* @brief image class with shallow copy
* @author Pascal Monasse <[email protected]>
*
* Copyright (c) 2012-2013, Pascal Monasse
* All rights reserved.
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* You should have received a copy of the GNU General Pulic License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "image.h"
#include "io_png.h"
#include <algorithm>
#include <cassert>
/// Constructor
Image::Image(int width, int height)
: count(new int(1)), tab(new float[width*height]), w(width), h(height) {}
/// Constructor with array of pixels.
///
/// Make sure it is not deleted during the lifetime of the image.
Image::Image(float* pix, int width, int height)
: count(0), tab(pix), w(width), h(height) {}
/// Copy constructor (shallow copy)
Image::Image(const Image& I)
: count(I.count), tab(I.tab), w(I.w), h(I.h) {
if(count)
++*count;
}
/// Assignment operator (shallow copy)
Image& Image::operator=(const Image& I) {
if(count != I.count) {
kill();
if(I.count)
++*I.count;
}
count=I.count; tab=I.tab; w=I.w; h=I.h;
return *this;
}
/// Deep copy
Image Image::clone() const {
Image I(w,h);
std::copy(tab, tab+w*h, I.tab);
return I;
}
/// Free memory
void Image::kill() {
if(count && --*count == 0) {
delete count;
delete [] tab;
}
}
/// Addition
Image Image::operator+(const Image& I) const {
assert(w==I.w && h==I.h);
Image S(w,h);
float* out=S.tab;
const float *in1=tab, *in2=I.tab;
for(int i=w*h-1; i>=0; i--)
*out++ = *in1++ + *in2++;
return S;
}
/// Addition
Image& Image::operator+=(const Image& I) {
assert(w==I.w && h==I.h);
float* out=tab;
const float *in=I.tab;
for(int i=w*h-1; i>=0; i--)
*out++ += *in++;
return *this;
}
/// Subtraction
Image Image::operator-(const Image& I) const {
assert(w==I.w && h==I.h);
Image S(w,h);
float* out=S.tab;
const float *in1=tab, *in2=I.tab;
for(int i=w*h-1; i>=0; i--)
*out++ = *in1++ - *in2++;
return S;
}
/// Pixel-wise multiplication
Image Image::operator*(const Image& I) const {
assert(w==I.w && h==I.h);
Image S(w,h);
float* out=S.tab;
const float *in1=tab, *in2=I.tab;
for(int i=w*h-1; i>=0; i--)
*out++ = *in1++ * *in2++;
return S;
}
/// Save \a disparity image in 8-bit PNG image.
///
/// The disp->gray function is affine: gray=a*disp+b.
/// Pixels outside [0,255] are assumed invalid and written in cyan color.
bool save_disparity(const char* fileName, const Image& disparity,
int dMin, int dMax, int grayMin, int grayMax)
{
const float a=(grayMax-grayMin)/float(dMax-dMin);
const float b=(grayMin*dMax-grayMax*dMin)/float(dMax-dMin);
const int w=disparity.width(), h=disparity.height();
const float* in=&(const_cast<Image&>(disparity))(0,0);
unsigned char *out = new unsigned char[3*w*h];
unsigned char *red=out, *green=out+w*h, *blue=out+2*w*h;
for(size_t i=w*h; i>0; i--, in++, red++) {
if((float)dMin<=*in && *in<=(float)dMax) {
float v = a * *in + b +0.5f;
if(v<0) v=0;
if(v>255) v=255;
*red = static_cast<unsigned char>(v);
*green++ = *red;
*blue++ = *red;
} else { // Cyan for disparities out of range
*red=0;
*green++ = *blue++ = 255;
}
}
bool ok = (io_png_write_u8(fileName, out, w, h, 3) == 0);
delete [] out;
return ok;
}