Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
DeInterlace.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 #include "DeInterlace.hh"
27 
28 #include <Base/Common/BIASpragma.hh>
29 #include <Base/Image/ImageConvert.hh>
30 
31 using namespace BIAS;
32 using namespace std;
33 
34 //////////////////////////////////////////////////////////////////////////
35 // implementation
36 //////////////////////////////////////////////////////////////////////////
37 
38 template <class InputStorageType, class OutputStorageType>
40 DeInterlace() : FilterNToN<InputStorageType, OutputStorageType>()
41 {
42  bUseEvenLines_ = true;
43  bDoDownSamplingByTwo_ = false;
45 }
46 
47 template <class InputStorageType, class OutputStorageType>
50  : FilterNToN<InputStorageType, OutputStorageType>(),
51  bUseEvenLines_(other.bUseEvenLines_),
52  bDoDownSamplingByTwo_(other.bDoDownSamplingByTwo_),
53  eDeInterlaceType_(other.eDeInterlaceType_)
54 {
55 }
56 
57 template <class InputStorageType, class OutputStorageType>
60 {
61 }
62 
63 template <class InputStorageType, class OutputStorageType>
66 {
67  BIASCDOUT(D_FILTERBASE_CALLSTACK, "DeInterlace::Filter\n");
68  int res = 0;
69 
70  register double sum=0.0;
71  const InputStorageType **psrc;
72  OutputStorageType **pdst;
73 
74  register const int width = src.GetWidth();
75  register const int height= src.GetHeight();
76  register const int cc= src.GetChannelCount();
77  //this is bad case just copy the even to odd lines or vice versa
78  if(!bDoDownSamplingByTwo_){
79  if(!dst.SamePixelAndChannelCount(src) || dst.IsEmpty()) {
80  dst.Release();
81  dst.Init(src.GetWidth(),src.GetHeight(),src.GetChannelCount(),
82  src.GetStorageType(),src.IsInterleaved());
83  }
84  //go to beginnig of first row "0"
85  psrc = src.GetImageDataArray();
86  pdst = dst.GetImageDataArray();
87  //use even lines 0,2,4,6...
88  int line=0;
89  if(bUseEvenLines_)
90  {
91  for(int i=0;i<height;i++){
92  //even line
93  if ( (i % 2) == 0)line = i;
94  else line = i-1;
95  for(int j=0;j<width;j++){
96  for(int c=0;c<cc;c++){
97  pdst[i][j*cc+c] = (OutputStorageType)psrc[line][j*cc+c];
98  }
99  }
100  }
101  }
102  //use odd lines 1,3,5...
103  else
104  {
105  for(int i=1;i<height-1;i++){
106  //odd line
107  if ( (i % 2) == 0)line = i+1;
108  else line = i;
109  for(int j=0;j<width;j++){
110  for(int c=0;c<cc;c++){
111  pdst[i][j*cc+c] = (OutputStorageType)psrc[line][j*cc+c];
112  }
113  }
114  }
115  }
116  } //end !bDoDownSamplingByTwo_
117  else{
118  if(dst.GetWidth()!= src.GetWidth()/2 ||
119  dst.GetHeight() != src.GetHeight()/2 ||
120  dst.GetChannelCount() != src.GetChannelCount()||
121  dst.IsEmpty())
122  {
123  dst.Release();
124  dst.Init(src.GetWidth()/2,src.GetHeight()/2,
125  src.GetChannelCount(), src.GetStorageType(), src.IsInterleaved());
126  }
127  //go to beginnig of first row "0"
128  psrc = src.GetImageDataArray();
129  pdst = dst.GetImageDataArray();
130  //use even lines 0,2,4,6...
131  if(bUseEvenLines_)
132  {
133  int jtwo = 0;
134  int itwo = 0;
135  for(int i=0;i<height/2;i++){
136  for(int j=0;j<width/2;j++){
137  jtwo = 2*j; itwo = 2*i;
138 
139  for(int c=0;c<cc;c++){
140 
141  switch(eDeInterlaceType_)
142  {
143  case BIAS_DI_121:
144  if(j==0)//beginning of row
145  sum = (psrc[itwo][0*cc+c]+psrc[itwo][1*cc+c])/2;
146  else if(j==(width/2)-1) // end of row
147  sum = (psrc[itwo][(jtwo-1)*cc+c]+psrc[itwo][jtwo*cc+c])/2;
148  else // in between
149  sum = double( (psrc[itwo][(jtwo-1)*cc+c] + psrc[itwo][jtwo*cc+c]*2 + psrc[itwo][(jtwo+1)*cc+c])/4 );
150  break;
151  case BIAS_DI_22:
152  if(j==0)//beginning of row
153  sum = (psrc[itwo][0*cc+c]+psrc[itwo][1*cc+c])/2;
154  else // rest of row
155  sum = (psrc[itwo][(jtwo-1)*cc+c]+psrc[itwo][jtwo*cc+c])/2;
156  break;
157  }
158  pdst[i][j*cc+c] = (OutputStorageType)sum;
159  }
160  }
161  }
162  }
163  //use odd lines 1,3,5...
164  else
165  {
166  int jtwo = 0;
167  int itwo = 0;
168  for(int i=1;i<height/2;i++)
169  for(int j=0;j<width/2;j++){
170  jtwo = 2*j; itwo = (2*i)-1;
171 
172  for(int c=0;c<cc;c++){
173 
174  switch(eDeInterlaceType_)
175  {
176  case BIAS_DI_121:
177  if(j==0)//beginning of row
178  sum = (psrc[itwo][0*cc+c]+psrc[itwo][1*cc+c])/2;
179  else if(j==(width/2)-1) // end of row
180  sum = (psrc[itwo][(jtwo-1)*cc+c]+psrc[itwo][jtwo*cc+c])/2;
181  else // in between
182  sum = (psrc[itwo][(jtwo-1)*cc+c] + psrc[itwo][jtwo*cc+c]*2 + psrc[itwo][(jtwo+1)*cc+c])/4;
183  break;
184  case BIAS_DI_22:
185  if(j==0)//beginning of row
186  sum = (psrc[itwo][0*cc+c]+psrc[itwo][1*cc+c])/2;
187  else // rest of row
188  sum = (psrc[itwo][(jtwo-1)*cc+c]+psrc[itwo][jtwo*cc+c])/2;
189  break;
190  }
191  pdst[i][j*cc+c] = (OutputStorageType)sum;
192  }
193  }
194  }
195  } //end downsampling != 1.0
196  return res;
197 }
198 
199 template <class InputStorageType, class OutputStorageType>
202 {
203  BIASERR("Unimplemented interface, calling generic Filter");
204  return Filter(src, dst);
205 }
206 
207 template <class InputStorageType, class OutputStorageType>
210 {
211  BIASERR("Unimplemented interface, calling generic Filter");
212  return Filter(src, dst);
213 }
214 
215 
216 template <class InputStorageType, class OutputStorageType>
220 
221 
222  Image<InputStorageType> srcCopy,temp;
223 
224  int width = src.GetWidth();
225  int height = src.GetHeight();
226 
227  // use planar image in order to apply deinterlace filter seperately to each channel for now
228  if (!((src.GetColorModel() == ImageBase::CM_RGB) && src.IsPlanar())) {
229  temp = src;
230  ImageConvert::Convert(temp, srcCopy, ImageBase::CM_RGB, true);
231  } else {
232  srcCopy = src;
233  }
234 
235 /*
236  if (src.GetColorModel() != ImageBase::CM_RGB) {
237  BIASERR("ColorModel is not CM_RGB");
238  return -1;
239  }
240 
241  if (!src.IsPlanar()) {
242  ImageConvert::ToPlanar(src,srcCopy);
243  } else {
244  srcCopy = src; // ok?
245  }
246 */
247  Image<InputStorageType> red(width, height, 1);
248  Image<OutputStorageType> redG(width, height, 1);
249  Image<InputStorageType> green(width, height, 1);
250  Image<OutputStorageType> greenG(width, height, 1);
251  Image<InputStorageType> blue(width, height, 1);
252  Image<OutputStorageType> blueG(width, height, 1);
253 
254  red.GetChannel(srcCopy, 0);
255  green.GetChannel(srcCopy, 1);
256  blue.GetChannel(srcCopy, 2);
257 
258  Filter(red, redG);
259  Filter(green, greenG);
260  Filter(blue, blueG);
261 
262  width = redG.GetWidth();
263  height = redG.GetHeight();
264 
265  dst = Image<OutputStorageType>(width, height, 3, true);
266  for (int i =0; i < width; i++) {
267  for (int j=0; j < height; j++) {
268  dst.SetPixel(redG.PixelValue(i, j), i, j, 0);
269  dst.SetPixel(greenG.PixelValue(i, j), i, j, 1);
270  dst.SetPixel(blueG.PixelValue(i, j), i, j, 2);
271  }
272  }
273 
274  return 0 ;
275 }
276 
277 
278 
279 
280 template <class InputStorageType, class OutputStorageType>
282 SetUseEvenLines(bool bEvenLines)
283 {
284  bUseEvenLines_ = bEvenLines;
285 }
286 
287 template <class InputStorageType, class OutputStorageType>
290 {
291  eDeInterlaceType_ = type;
292 }
293 
294 
295 template <class InputStorageType, class OutputStorageType>
297 SetDownSamplingByTwo(bool bDoDownSamplingByTwo )
298 {
299  bDoDownSamplingByTwo_ = bDoDownSamplingByTwo;
300 }
301 
302 //////////////////////////////////////////////////////////////////////////
303 // instantiation
304 //////////////////////////////////////////////////////////////////////////
305 namespace BIAS{
306 #define FILTER_INSTANTIATION_CLASS DeInterlace
307 //#define FILTER_INSTANTIATION_NO_UNSIGNED_OUTPUT
308 #include "Filterinst.hh"
309 }
void Release()
reimplemented from ImageBase
Definition: Image.cpp:1579
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
Definition: ImageBase.hh:245
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
averages over a region with constant weights
Definition: DeInterlace.cpp:65
bool IsInterleaved() const
Definition: ImageBase.hh:491
BIAS_DEINTERLACE_TYPE
the type of deinterlacing: BIAS_DI_121 : calculate new pixel from old neighbouring pixels with new = ...
Definition: DeInterlace.hh:41
bool IsPlanar() const
Definition: ImageBase.hh:484
bool bDoDownSamplingByTwo_
Definition: DeInterlace.hh:99
unsigned int GetWidth() const
Definition: ImageBase.hh:312
StorageType PixelValue(const unsigned int x, const unsigned int y, const unsigned short int channel=0) const
Returns value of pixel at specific position, using specific channel as offset.
Definition: Image.hh:91
Deinterlacer filter for images.
Definition: DeInterlace.hh:57
int GetChannel(const ImageBase &source, const unsigned int channel)
copies one specific channel from source to Image can only be called from an planar image...
Definition: ImageBase.cpp:428
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
base class for simple n-&gt;n filter implementations
Definition: FilterNToN.hh:43
void SetUseEvenLines(bool bEvenLines=true)
Set if the even or odd lines in the images should be used.
unsigned int GetHeight() const
Definition: ImageBase.hh:319
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same &quot;size&quot; as Image of other type
Definition: ImageBase.hh:73
virtual int FilterInt(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
only calls filter, for consistency of params
void SetPixel(const StorageType &value, const unsigned int &x, const unsigned int &y, const unsigned short int channel=0)
Set the value of a given pixel (x,y) in channel to value.
Definition: Image.hh:171
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
Definition: Image.cpp:421
void SetDownSamplingByTwo(bool bDoDownSamplingByTwo=true)
Set the downsampling factor while filter.
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
void SetDeInterlaceType(BIAS_DEINTERLACE_TYPE type)
Set the Type of deinterlacing e.g.
BIAS_DEINTERLACE_TYPE eDeInterlaceType_
Definition: DeInterlace.hh:100
static int Convert(BIAS::ImageBase &source, BIAS::ImageBase &dest, enum BIAS::ImageBase::EColorModel targetColorModel, bool bPlanar=false)
main general conversion function, calls desired specialized functions, always initializes the destIma...
enum EStorageType GetStorageType() const
Definition: ImageBase.hh:414
virtual int FilterFloat(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
only calls filter, for consistency of params
virtual ~DeInterlace()
Definition: DeInterlace.cpp:59
virtual int FilterColorImg(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
applies deinterlacing to each channel sperately
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase
Definition: Image.hh:153