モノクロ写真をカラー写真にするソフト

まず、カラー写真を完全にモノクロにしちゃいます。画像編集ソフトなどを使用してください。

 

 

 

 

 

これで、カラーデータがなくなりました。

次に、このソフトの8行目にhnc.pngと書いてありますが、これが、モノクロ写真のファイル名なので、カラーに直したい写真のファイル名をここに入れます。そして、processingの▶ボタンをおすと・・・

⇦こうなります。

かなり元の色に近い!!

再現されています。

 

 

 

色滲みZipダウンロードは、こちら

ソースコード☟8行目のファイル名は、自分がカラーにしてみたい写真の名前にしてください。

 

//String name = "hnnc.png-outm.jpg";
boolean yes = false;
boolean no = true;




String name = "hnc.png";
boolean jpeg = no;

int nois = 0;

float[] yuv(float r, float g, float b) {
  float[] o = {0, 0, 0};
  o[0]=0.299*r+0.587*g+0.114*b;
  o[1]=0.5*r-0.419*g-0.081*b+128;
  o[2]=-0.169*r-0.332*g+0.5*b+128; 
  return o;
}
color rgb(float y, float cr, float cb) {
  float[] o = {0, 0, 0};
  o[0] = y+(cr*1.402);
  o[1] = y-(cr*0.714)-(cb*0.344);
  o[2] = y+(cb*1.772);
  /*
  R  = Y+1.402Cr
   G  = Y-0.714Cr-0.344Cb
   B  = Y+1.772Cb
   */
  return color(o[0], o[1], o[2]);
}
float pcr, pcb;
PImage i;
PImage back;
int m = 0b10000000;
PGraphics pg;
PGraphics pg2;
PGraphics pgmono;
//hsync = 160
//none = 42
//vsync = 3
int g;
int[] bu = new int[386400];
byte[] da = new byte[386400+256];
void setup() {
  println(millis()+"ms "+"起動");
  size(800, 483);
  noStroke();
  //noSmooth();
  background(0, 255, 0);
  println(millis()+"ms "+"画像ロード開始");
  i = loadImage(name);
  back = loadImage("back.png");
  println(millis()+"ms "+"画像ロード終了");
  println(millis()+"ms "+"createGraphics開始");
  pg = createGraphics(640, 480);
  pg2 = createGraphics(640, 480);
  pgmono = createGraphics(640, 480);
  println(millis()+"ms "+"createGraphics終了");
  //image(back, 0, 0);
  //for (int ii = 800-640; ii > 0; ii--) {
  println(millis()+"ms "+"画像表示開始");
  if (jpeg) {
    image(i, 3, 0, i.width, i.height);
  } else {
    image(i, 0, 0, i.width, i.height);
  }
  println(millis()+"ms "+"画像表示完了");
  //}
  ///background(128,0,128);
  //pg.noStroke();
  pg.noSmooth();
  pgmono.noSmooth();
  smooth(4);
  pg.beginDraw();
  pgmono.beginDraw();
  pg.background(0);
  pgmono.background(0);
  scale(1, 1);
  //pg.scale(1,1);
  println(millis()+"ms "+"データ解析開始");
  for (int i = 0; i < 256; i++) {
    da[i] = byte(i);
  }
  for (int y = 0; y < 483; y++) {
    for (int x = 0; x < 800; x += 1) {
      //bu[x] =    int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[0]);  
      int xx = int(x/1);
      xx *= 1;
      bu[x] =    int(yuv(red(get(int(xx), y)), green(get(int(xx), y)), blue(get(int(xx), y)))[0]);  

      //bu[x*4+1] =    int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[0]);  
      //bu[x*4+2] =    int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[0]);  
      //bu[x*4+3] =    int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[0]);  

      if (g == 0)bu[x] +=   (int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[2])-127)/4;  
      if (g == 1)bu[x] += (int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[1])-127)/4;  
      if (g == 2)bu[x] -= (int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[2])-127)/4;  
      if (g == 3)bu[x] -= (int(yuv(red(get(int(x), y)), green(get(int(x), y)), blue(get(int(x), y)))[1])-127)/4; 
      g++;
      if (g == 4)g = 0;
      da[(y*800)+x+256] = byte(bu[x]/2+64);
      if (x > 640) {
        da[(y*800)+x+256] = byte(0);
      }
      if (x > 640 && y > 480) {
        da[(y*800)+x+256] = byte(0);
      }
      //da[(y*800)+x] = byte(da[(y*800)+x]^m);
      //println(bu[x]);
      bu[x] += random(-nois, nois);
    }

    pcr = 0;
    pcb = 0;
    float ya = 0;
    float yas = 0;
    float yasa = 0;
    float yasat = 0;
    for (int x = 0; x < 640/4; x++) {

      color c = color(128);

      float yy = ((bu[x*4]+bu[x*4+1]+bu[x*4+2]+bu[x*4+4])/4);
      float mono0 = ((bu[x*4]+bu[x*4+2])/2);
      float mono1 = ((bu[x*4+1]+bu[x*4+4])/2);
      float mono = yy;
      float cb = mono0-(bu[x*4+0]);
      float cr = mono1-(bu[x*4+3]);
      //if (cb > 255)cb = 255;
      //if (cr > 255)cr = 255;
      //if(cb < 255)cb = -cb;
      //if(cr < 255)cr = -cr
      cb = -cb;
      //acb = -acb;
      //acr = -acr;
      //cr = -cr;
      //cr += 20;
      //cb += 30;
      //println("理想cb "+(yuv(red(get(x,y)),green(get(x,y)),blue(get(x,y)))[2]-128));
      //println("cb "+cb);
      //println("理想cr "+(yuv(red(get(x,y)),green(get(x,y)),blue(get(x,y)))[1]-128));
      //println("cr "+cr);
      //println("0 "+cr);
      //println("1 "+acr);
      //println("cb"+cb);
      //println("cr"+cr);
      float mi = 0;
      //cr += mi;
      //cb -= 1;
      cr *= 5;
      cb *= 5;
      int co = 40;
      if (cr > co || cr < -co)cr = 0;
      if (cb > co || cb < -co)cb = 0;
      if (cr > 2  && cr < -2 )cr = 0;
      if (cb > 2  && cb < -2 )cb = 0;
      int ac = 128;
      if (cr > ac)cr = ac;
      if (cb > ac)cb = ac;
      if (cr < -ac)cr = -ac;
      if (cb < -ac)cb = -ac;
      //pcr = cr;
      //pcb = cb;
      pcr = (cr+pcr*2)/3;
      pcb = (cb+pcb*2)/3;
      c = rgb((bu[x*4]+bu[x*4+1]/8), ((cr-mi)*1), ((cb)*1));
      pg.set(x*2, y, c);
      //pg.point(x*2, y);
      //pg.stroke(c);
      //pg.point(x*2+1, y);
      //pg.stroke(color(255, 0, 0));
      //pg.point(x*2+1, 32);
      pg.set(x*2+1, y, c);
      float b = 1.1;
      int xx = 1;
      pgmono.set(int(x*4+0+xx), y, color(int(bu[x*4+0]/b)));
      pgmono.set(int(x*4+1+xx), y, color(int(bu[x*4+1]/b)));
      pgmono.set(int(x*4+2+xx), y, color(int(bu[x*4+2]/b)));
      pgmono.set(int(x*4+3+xx), y, color(int(bu[x*4+3]/b)));
      //println(int(bu[x*4+0]/b));
      //pg.point(x*4+2, y);
      //pg.point(x*4+3, y);
      //println((s1-s2));
    }
  }
  println(millis()+"ms "+"データ解析終了");
  pg.endDraw();
  pgmono.endDraw();
  pg2.beginDraw();
  println(millis()+"ms "+"画像拡大開始");
  for (int y = 0; y < 480; y++) {
    for (int x = 0; x < 640/2; x++) {
      float rr;
      float gg;
      float bb;
      rr = red(pg.get(x, y));
      gg = green(pg.get(x, y));
      bb = blue(pg.get(x, y));
      pg2.set(x*2, y, color(rr, gg, bb));

      float r;
      float g;
      float b;
      r = red(pg.get(x, y));
      g = green(pg.get(x, y));
      b = blue(pg.get(x, y));
      r += red(pg.get(x+1, y));
      g += green(pg.get(x+1, y));
      b += blue(pg.get(x+1, y));
      r /= 2;
      g /= 2;
      b /= 2;
      pg2.set(x*2+1, y, color(r, g, b));
    }
  }
  for (int y = 0; y < 480; y++) {
    float ys = 0;
    for (int x = 0; x < 640; x++) {
      float rr;
      float gg;
      float bb;
      rr = red(pg2.get(x, y));
      gg = green(pg2.get(x, y));
      bb = blue(pg2.get(x, y));
      float[] temp = yuv(rr, gg, bb);
      float ya = temp[0];
      float ua = temp[1];
      float va = temp[2];
      ys = (ya+ys*2)/3;
      float ty = ((ya-ys)*10)-64;
      ty = (ty/8)+ys;
      ty += 2;
      float hue = 1.1;
      pg2.set(x, y, rgb(ty,(ua-128)*hue,(va-128)*hue));
    }
  }
  println(millis()+"ms "+"画像拡大終了");
  println(millis()+"ms "+"画像表示開始");
  pg2.endDraw();
  image(pg2, 0, 0);
  println(millis()+"ms "+"画像表示終了");
  println(millis()+"ms "+"画像保存開始");
  pg2.get(0, 0, 640, 480).save(name+"-滲みカラー.png");
  pgmono.get(0, 0, 640, 480).save(name+"-モノ.png");
  println(millis()+"ms "+"画像保存終了");
  /*
  for (int i = 0; i < 386400+256; i++) {
   da[i] = byte(da[i]^m);
   }
   saveBytes(name+"-out-comad.raw", da);
   //exit();
   */
}

実は、このモノクロ写真(サイズ640×480)は、横4ドットごとに明るさが変わるようにプログラムで操作して、この縞模様をプログラムで抜き取ってカラー写真にしています。

これは、YUVという色にじみを利用しています。

ウィキペディア「YUV」参照

https://ja.wikipedia.org/wiki/YUV

でも、色にじみ??YUV??なんじゃらほい?????

というKOHAママのような方は、次の投稿をご覧ください。

KOHAママの理解力がなさすぎて、KOHA兄が5分で書いてくれたYUV解説ソフトを次に紹介します。

 

 

Follow me!

コメントを残す