如何从数码相机的raw照片中提取Bayer Pattern Image和raw照片参数

  现在大多数的数码相机都带拍摄raw照片的功能,和直出的jpeg照片不同,raw片具有很大的后期处理空间。Adobe制定了DNG(Digital Negative)规范,这个规范目前已经到了版本1.4。DNG是开放的规范,大家只要有兴趣,都可以到Adobe的网站下下载Digital Negative (DNG) Specification。虽然DNG是开放的规范,但是大多数的大牌数码相机厂商还不支持DNG,因此Adobe搞了个DNGConverter。

 

  有了raw照片,你可以用ps或light room做后期。如果你想自己做raw照片处理呢?那么请跟随ispforfun的脚步,ispforfun将带你走进数字图像处理。

 

  让我们从raw照片的参数提取和Bayer Pattern Image的分离开始吧。

 

  LibRaw: http://www.libraw.org/

  LibRaw的工程中包含了一个应用程序unprocessed_raw,让我们一起改造这个应用程序。

 

/* -*- C++ -*-
 * File: unprocessed_raw.cpp
 * Copyright 2009-2013 LibRaw LLC ([email protected])
 * Created: Fri Jan 02, 2009
 *
 * LibRaw sample
 * Generates unprocessed raw image: with masked pixels and without black subtraction
 *

LibRaw is free software; you can redistribute it and/or modify
it under the terms of the one of three licenses as you choose:

1. GNU LESSER GENERAL PUBLIC LICENSE version 2.1
   (See file LICENSE.LGPL provided in LibRaw distribution archive for details).

2. COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
   (See file LICENSE.CDDL provided in LibRaw distribution archive for details).

3. LibRaw Software License 27032010
   (See file LICENSE.LibRaw.pdf provided in LibRaw distribution archive for details).

 */

/*
   Modified by ispforfun
   1. add more dump information for camera raw images.
   2. write out naive raw file.
*/
 
#include 
#include 
#include 
#include 
#ifndef WIN32
#include 
#else
#include 
#include 
#endif

#include "libraw/libraw.h"

#ifdef WIN32
#define snprintf _snprintf
#endif

#if !(LIBRAW_COMPILE_CHECK_VERSION_NOTLESS(0,14))
#error This code is for LibRaw 0.14+ only
#endif

void  gamma_curve (unsigned short curve[]);
void write_ppm(unsigned width, unsigned height, unsigned short *bitmap, const char *basename);
void write_tiff(int width, int height, unsigned short *bitmap, const char *basename);
// added by ispforfun
void write_raw(int width, int height, unsigned short *bitmap, const char *fn);


int main(int ac, char *av[])
{
    int  i, ret;
    int verbose=1,autoscale=0,use_gamma=0,out_tiff=0,out_raw=0;
    char outfn[1024];
    char outrawfn[1024];	

    LibRaw RawProcessor;
    if(ac<2) 
        {
          usage:
            printf(
                "unprocessed_raw - LibRaw %s sample. %d cameras supported\n"
                "Usage: %s [-q] [-A] [-g] [-s N] raw-files....\n"
                "\t-q - be quiet\n"
                "\t-s N - select Nth image in file (default=0)\n"
                "\t-g - use gamma correction with gamma 2.2 (not precise,use for visual inspection only)\n"
                "\t-A - autoscaling (by integer factor)\n"
                "\t-T - write tiff instead of pgm\n"
                "\t-r - write naive raw file\n"
                ,LibRaw::version(),
                LibRaw::cameraCount(),
                av[0]);
            return 0;
        }
    
#define S RawProcessor.imgdata.sizes
#define C RawProcessor.imgdata.color
#define INFO RawProcessor.imgdata.idata
#define OUT RawProcessor.imgdata.params

    for (i=1;i0 && max< 1<<15)
                        {
                            scale = (1<<16)/max;
                            if(verbose)
                                printf("Scaling with multiplier=%d (max=%d)\n",scale,max);
                            
                            for(int j=0; j= 1] = 1;
  if (g[1] && (g[1]-1)*(g[0]-1) <= 0) {
    for (i=0; i < 48; i++) {
      g[2] = (bnd[0] + bnd[1])/2;
      if (g[0]) bnd[(pow(g[2]/g[1],-g[0]) - 1)/g[0] - 1/g[2] > -1] = g[2];
      else	bnd[g[2]/exp(1-1/g[2]) < g[1]] = g[2];
    }
    g[3] = g[2] / g[1];
    if (g[0]) g[4] = g[2] * (1/g[0] - 1);
  }
  if (g[0]) g[5] = 1 / (g[1]*SQR(g[3])/2 - g[4]*(1 - g[3]) +
		(1 - pow(g[3],1+g[0]))*(1 + g[4])/(1 + g[0])) - 1;
  else      g[5] = 1 / (g[1]*SQR(g[3])/2 + 1
		- g[2] - g[3] -	g[2]*g[3]*(log(g[3]) - 1)) - 1;
  for (i=0; i < 0x10000; i++) {
    curve[i] = 0xffff;
    if ((r = (double) i / imax) < 1)
      curve[i] = 0x10000 * ( mode
	? (r < g[3] ? r*g[1] : (g[0] ? pow( r,g[0])*(1+g[4])-g[4]    : log(r)*g[2]+1))
	: (r < g[2] ? r/g[1] : (g[0] ? pow((r+g[4])/(1+g[4]),1/g[0]) : exp((r-1)/g[2]))));
  }
}


void tiff_set (ushort *ntag,
	ushort tag, ushort type, int count, int val)
{
  struct tiff_tag *tt;
  int c;

  tt = (struct tiff_tag *)(ntag+1) + (*ntag)++;
  tt->tag = tag;
  tt->type = type;
  tt->count = count;
  if (type < 3 && count <= 4)
      for(c=0;c<4;c++) tt->val.c[c] = val >> (c << 3);
  else if (type == 3 && count <= 2)
      for(c=0;c<2;c++) tt->val.s[c] = val >> (c << 4);
  else tt->val.i = val;
}
#define TOFF(ptr) ((char *)(&(ptr)) - (char *)th)


void tiff_head (int width, int height, struct tiff_hdr *th)
{
  int c;
  time_t timestamp = time(NULL);
  struct tm *t;

  memset (th, 0, sizeof *th);
  th->t_order = htonl(0x4d4d4949) >> 16;
  th->magic = 42;
  th->ifd = 10;
  tiff_set (&th->ntag, 254, 4, 1, 0);
  tiff_set (&th->ntag, 256, 4, 1, width);
  tiff_set (&th->ntag, 257, 4, 1, height);
  tiff_set (&th->ntag, 258, 3, 1, 16);
  for(c=0;c<4;c++) th->bps[c] = 16;
  tiff_set (&th->ntag, 259, 3, 1, 1);
  tiff_set (&th->ntag, 262, 3, 1, 1);
  tiff_set (&th->ntag, 273, 4, 1, sizeof *th);
  tiff_set (&th->ntag, 277, 3, 1, 1);
  tiff_set (&th->ntag, 278, 4, 1, height);
  tiff_set (&th->ntag, 279, 4, 1, height*width*2);
  tiff_set (&th->ntag, 282, 5, 1, TOFF(th->rat[0]));
  tiff_set (&th->ntag, 283, 5, 1, TOFF(th->rat[2]));
  tiff_set (&th->ntag, 284, 3, 1, 1);
  tiff_set (&th->ntag, 296, 3, 1, 2);
  tiff_set (&th->ntag, 306, 2, 20, TOFF(th->date));
  th->rat[0] = th->rat[2] = 300;
  th->rat[1] = th->rat[3] = 1;
  t = localtime (×tamp);
  if(t)
      sprintf (th->date, "%04d:%02d:%02d %02d:%02d:%02d",
               t->tm_year+1900,t->tm_mon+1,t->tm_mday,t->tm_hour,t->tm_min,t->tm_sec);
}

void write_tiff(int width, int height, unsigned short *bitmap, const char *fn)
{
  struct tiff_hdr th;

  FILE *ofp = fopen(fn,"wb");
  if(!ofp) return;
  tiff_head (width,height,&th);
  fwrite (&th, sizeof th, 1, ofp);
  fwrite (bitmap, 2, width*height, ofp);
  fclose(ofp);
}

// added by ispforfun. 
void write_raw(int width, int height, unsigned short *bitmap, const char *fn)
{
  FILE *ofp = fopen(fn,"wb");
  if(!ofp) return;
  fwrite (bitmap, 2, width*height, ofp);
  fclose(ofp);
}


 


你可能感兴趣的:(数字图像处理)