YARP
Yet Another Robot Platform
 
Loading...
Searching...
No Matches
ImageUtils.cpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2006-2021 Istituto Italiano di Tecnologia (IIT)
3 * SPDX-License-Identifier: BSD-3-Clause
4 */
5
7#include <cstring>
8#include <algorithm> // std::math
9#include <yarp/os/Log.h>
10#include <yarp/os/LogStream.h>
11
12using namespace yarp::sig;
13
14static bool checkImages(const Image& bigImg, const Image& smallImg1, const Image& smallImg2)
15{
16 return bigImg.getPixelCode() == smallImg1.getPixelCode() &&
17 bigImg.getPixelCode() == smallImg2.getPixelCode() &&
18 smallImg1.width() == smallImg2.width() &&
19 smallImg1.height() == smallImg2.height() &&
20 bigImg.getRawImageSize() == 2*smallImg1.getRawImageSize();
21
22}
23
24
25bool utils::vertSplit(const Image& inImg, Image& outImgL, Image& outImgR)
26{
27 outImgL.resize(inImg.width()/2, inImg.height());
28 outImgR.resize(inImg.width()/2, inImg.height());
29
30 if (!checkImages(inImg, outImgL, outImgR)) {
31 return false;
32 }
33
34 size_t inHeight = inImg.height();
35 size_t singleImage_rowSizeByte = outImgL.getRowSize();
36 unsigned char *pixelLeft = outImgL.getRawImage();
37 unsigned char *pixelRight = outImgR.getRawImage();
38 unsigned char *pixelInput = inImg.getRawImage();
39
40 for(size_t h=0; h<inHeight; h++)
41 {
42 // Copy the memory
43 memcpy(pixelLeft + h*singleImage_rowSizeByte, pixelInput, singleImage_rowSizeByte);
44 memcpy(pixelRight + h*singleImage_rowSizeByte, pixelInput+=singleImage_rowSizeByte, singleImage_rowSizeByte);
45
46 // Update the pointers
47 pixelInput+= singleImage_rowSizeByte;
48 }
49 return true;
50}
51
52bool utils::horzSplit(const Image& inImg, Image& outImgUp, Image& outImgDown)
53{
54 outImgUp.resize(inImg.width(), inImg.height()/2);
55 outImgDown.resize(inImg.width(), inImg.height()/2);
56
57 if (!checkImages(inImg, outImgUp, outImgDown)) {
58 return false;
59 }
60 // Copy the memory
61 size_t imgSize = outImgUp.getRawImageSize();
62 memcpy(outImgUp.getRawImage(), inImg.getRawImage(), imgSize);
63 memcpy(outImgDown.getRawImage(), inImg.getRawImage() + imgSize, imgSize);
64 return true;
65}
66
67
68
69bool utils::horzConcat(const Image& inImgL, const Image& inImgR, Image& outImg)
70{
71 outImg.resize(inImgL.width()*2, inImgL.height());
72
73 if (!checkImages(outImg, inImgL, inImgR)) {
74 return false;
75 }
76
77 size_t singleImage_rowSizeByte = inImgL.getRowSize();
78 unsigned char * pixelLeft = inImgL.getRawImage();
79 unsigned char * pixelRight = inImgR.getRawImage();
80 unsigned char * pixelOutLeft = outImg.getRawImage();
81 unsigned char * pixelOutRight = outImg.getRawImage() + singleImage_rowSizeByte;
82
83 size_t height = inImgL.height();
84
85 for(size_t h=0; h<height; h++)
86 {
87 // Copy the memory
88 memcpy(pixelOutLeft, pixelLeft, singleImage_rowSizeByte);
89 memcpy(pixelOutRight, pixelRight, singleImage_rowSizeByte);
90
91 // Update the pointers
92 pixelOutLeft += 2*singleImage_rowSizeByte;
93 pixelOutRight += 2*singleImage_rowSizeByte;
94 pixelLeft += singleImage_rowSizeByte;
95 pixelRight += singleImage_rowSizeByte;
96 }
97 return true;
98}
99
100bool utils::vertConcat(const Image& inImgUp, const Image& inImgDown, Image& outImg)
101{
102 outImg.resize(inImgUp.width(), inImgUp.height()*2);
103
104 if (!checkImages(outImg, inImgUp, inImgDown)) {
105 return false;
106 }
107
108 // Copy the memory
109 size_t imgSize = inImgUp.getRawImageSize();
110 memcpy(outImg.getRawImage(), inImgUp.getRawImage(), imgSize);
111 memcpy(outImg.getRawImage() + imgSize, inImgDown.getRawImage(), imgSize);
112 return true;
113}
114
116 const std::pair<unsigned int, unsigned int>& vertex1,
117 const std::pair<unsigned int, unsigned int>& vertex2,
118 yarp::sig::Image& outImg)
119{
120 if (inImg.getPixelCode() != outImg.getPixelCode()) {
121 return false;
122 }
123
124 // Normalize vertices: upper-left (tlx,tly) and bottom-right (brx,bry) corners
125 auto tlx = std::min(vertex1.first, vertex2.first);
126 auto tly = std::min(vertex1.second, vertex2.second);
127 auto brx = std::max(vertex1.first, vertex2.first);
128 auto bry = std::max(vertex1.second, vertex2.second);
129
130 if (!inImg.isPixel(brx, bry)) {
131 return false;
132 }
133
134 outImg.resize(brx - tlx + 1, bry - tly + 1); // width, height
135
136 auto * pixelOut = outImg.getRawImage();
137
138 for (unsigned int row = 0; row < outImg.height(); row++) {
139 const auto * pixelIn = inImg.getPixelAddress(tlx, tly + row);
140 memcpy(pixelOut, pixelIn, outImg.getRowSize());
141 pixelOut += outImg.getRowSize();
142 }
143
144 return true;
145}
146
147bool utils::sum(Image& OutImg, const Image& InImg, bool enable_colorkey, int colorkey, bool enable_alpha, float alpha, size_t offset_x, size_t offset_y)
148{
149 if (OutImg.getPixelCode() != InImg.getPixelCode())
150 {
151 yError() << "utils::sum() Input and Output images must have the same pixelcode";
152 return false;
153 }
154
155 if (InImg.getPixelCode() != VOCAB_PIXEL_RGB)
156 {
157 yError() << "utils::sum() Unimplemented pixelcode";
158 return false;
159 }
160
161 yarp::sig::PixelRgb ColorkeyRGB;
162 ColorkeyRGB = *reinterpret_cast<yarp::sig::PixelRgb*>(&colorkey);
163
164 size_t yis = InImg.height();
165 size_t xis = InImg.width();
166 size_t yos = OutImg.height();
167 size_t xos = OutImg.width();
168
169 for (size_t y = 0; y < yis; ++y)
170 {
171 for (size_t x = 0; x < xis; ++x)
172 {
173 size_t xo = x + offset_x;
174 size_t yo = y + offset_y;
175 if (xo > xos) {
176 xo = xos;
177 }
178 if (yo > yos) {
179 yo = yos;
180 }
181
182 unsigned char* layer_pointer = InImg.getPixelAddress(x, y);
183 unsigned char* outimg_pointer = OutImg.getPixelAddress(xo, yo);
184
185 yarp::sig::PixelRgb* layer_pointer_rgb = reinterpret_cast<yarp::sig::PixelRgb*>(layer_pointer);
186 yarp::sig::PixelRgb* outimg_pointer_rgb = reinterpret_cast<yarp::sig::PixelRgb*>(outimg_pointer);
187
188 if (enable_colorkey && layer_pointer_rgb->r == ColorkeyRGB.r && layer_pointer_rgb->g == ColorkeyRGB.g && layer_pointer_rgb->b == ColorkeyRGB.b)
189 {
190 continue;
191 }
192 else if (enable_alpha)
193 {
194 outimg_pointer_rgb->r = layer_pointer_rgb->r * alpha + outimg_pointer_rgb->r * (1 - alpha);
195 outimg_pointer_rgb->g = layer_pointer_rgb->g * alpha + outimg_pointer_rgb->g * (1 - alpha);
196 outimg_pointer_rgb->b = layer_pointer_rgb->b * alpha + outimg_pointer_rgb->b * (1 - alpha);
197 }
198 else
199 {
200 outimg_pointer_rgb->r = layer_pointer_rgb->r;
201 outimg_pointer_rgb->g = layer_pointer_rgb->g;
202 outimg_pointer_rgb->b = layer_pointer_rgb->b;
203 }
204 }
205 }
206
207 return true;
208}
static bool checkImages(const Image &bigImg, const Image &smallImg1, const Image &smallImg2)
@ VOCAB_PIXEL_RGB
Definition Image.h:44
#define yError(...)
Definition Log.h:361
Base class for storing images.
Definition Image.h:79
size_t width() const
Gets width of image in pixels.
Definition Image.h:171
size_t getRowSize() const
Size of the underlying image buffer rows.
Definition Image.h:197
unsigned char * getRawImage() const
Access to the internal image buffer.
Definition Image.cpp:479
size_t getRawImageSize() const
Access to the internal buffer size information (this is how much memory has been allocated for the im...
Definition Image.cpp:488
void resize(size_t imgWidth, size_t imgHeight)
Reallocate an image to be of a desired size, throwing away its current contents.
Definition Image.cpp:402
bool isPixel(size_t x, size_t y) const
Check whether a coordinate lies within the image.
Definition Image.h:255
size_t height() const
Gets height of image in pixels.
Definition Image.h:177
virtual int getPixelCode() const
Gets pixel type identifier.
Definition Image.cpp:390
unsigned char * getPixelAddress(size_t x, size_t y) const
Get address of a pixel in memory.
Definition Image.h:245
bool vertSplit(const yarp::sig::Image &inImg, yarp::sig::Image &outImgL, yarp::sig::Image &outImgR)
Split vertically an image in two images of the same size.
bool cropRect(const yarp::sig::Image &inImg, const std::pair< unsigned int, unsigned int > &vertex1, const std::pair< unsigned int, unsigned int > &vertex2, yarp::sig::Image &outImg)
Crop a rectangle area out of an image given two opposite vertices.
bool horzSplit(const yarp::sig::Image &inImg, yarp::sig::Image &outImgUp, yarp::sig::Image &outImgDown)
Split horizontally an image in two images of the same size.
bool vertConcat(const yarp::sig::Image &inImgUp, const yarp::sig::Image &inImgDown, yarp::sig::Image &outImg)
Concatenate vertically two images of the same size in one with double height.
bool horzConcat(const yarp::sig::Image &inImgL, const yarp::sig::Image &inImgR, yarp::sig::Image &outImg)
Concatenate horizontally two images of the same size in one with double width.
bool sum(yarp::sig::Image &OutImg, const yarp::sig::Image &InImg, bool colorkey_enable, int colorkey, bool alpha_enable, float alpha, size_t off_x, size_t off_y)
applies an image on the top over another image.