カラー画像を白黒にしてみたい
カラー画像を白黒にしたい
NTSD加重平均方式風なもの
PPM画像をからR,G,Bの数値を取り、それに R*0.29891+G*0.58661+B*0.11448の計算結果を白黒画像のPGM画像に入力する、数値を作成します。
ところが、この計算結果は整数になるとは限らない。しかし、PGM画像では、数値は整数でなければならないから、誤差が生じる。私は、適当に四捨五入したので、作成した白黒画像がなんか違う感がすごくなりました。
あくまでNTSD加重平均方式風としたのはそのため。
↓
基本はPGM形式と同じ
PPM画像から数値を読み取る処理は、PGM形式の時とはあまり変わりませんでした。
変わったところは、RGBで3種類の数値を一つの集まりとして記録することとそれができるようにループの回数をうまいことやるくらいでした。
RGBを記録した後は、その3つの数値を用いて先ほどの式でPGM形式用の数値を出力するくらい。
プログラム
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
namespace カラー画像変換
{
internal static class Program
{
/// <summary>
/// アプリケーションのメイン エントリ ポイントです。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
//Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
class Form1 : Form
{
string range_st = new string[2];
int range_int = new int[2];
Label l = new Label[100];
string str = new string[100];
int leng;
bool P2 = false;
int youso = new int[1000];
string text;
string graphic;
string suuzi;
int[,] red;
int[,] green;
int[,] blue;
double[,] blwhf;
string[,] blwh;
public Form1()
{
StreamReader sr = new StreamReader(@"C:\Users\username\Desktop\c#\カラー画像変換\t.txt");
int count = 0;
while (0 <= sr.Peek())
{
str[count] = sr.ReadLine();
if (count >= 3)
{
str[count] += "E";//Eは改行記号の代わり
}
count++;
}
bool mozicheck = true;
count = 1;
leng = str[count].Length;
for (int i = 0; i < leng; i++)
{
char mozi;
mozi = str[count][i];
if(mozi != ' ')
{
if (mozicheck)
{
range_st[0] += mozi;
}
else
{
range_st[1] += mozi;
}
}
else
{
mozicheck = false;
}
}
range_int[0] = int.Parse(range_st[0]);
range_int[1] = int.Parse(range_st[1]);
int s = 0,c = 0;
bool loop = true;
red = new int[range_int[0],range_int[1]];
green = new int[range_int[0],range_int[1]];
blue = new int[range_int[0],range_int[1]];
for (int t =3;t <= 4; t++)
{
int color = 0;
s = 0;
int a = 0;
for (int y = 0;y <= range_int[1] * 3 - 1; y++)
{
if(y % 3 == 0 && y != 0)
{
a++;
}
while (true)
{
if(str[t][s] == ' ')
{
s++;
break;
}else if(str[t][s] == 'E')
{
break;
}
suuzi += str[t][s].ToString();
s++;
}
if (loop)
{
switch (color)
{
case 0:
red[c,a] = int.Parse(suuzi);
color++;
suuzi = null;
break;
case 1:
green[c,a] = int.Parse(suuzi);
color++;
suuzi = null;
break;
case 2:
blue[c,a] = int.Parse(suuzi);
color = 0;
suuzi = null;
break;
}
}
else
{
loop = true;
}
}
c++;
}
blwhf = new double[range_int[0], range_int[1]];
blwh = new string[range_int[0], range_int[1]];
for (int k = 0; k < range_int[0]; k++)
{
for (int i = 0; i < range_int[1]; i++)
{
blwhf[k,i] = red[k,i] * 0.29891 + blue[k,i] * 0.58661 + green[k, i] * 0.11448;
int b = (int)Math.Round(blwhf[k, i]);
blwh[k, i] = b.ToString();
}
}
string stra = System.IO.Directory.GetCurrentDirectory();
string[] textfile = Directory.GetFiles(stra);
bool filecheck = false;
foreach (string tex in textfile)
{
string file_name = Path.GetFileName(tex);
if (file_name == "b.pgm")
{
filecheck = true;
text = tex;
}
}
StreamWriter writer;
if (!filecheck)
{
FileStream fs = File.Create*1;
writer = new StreamWriter(fs);
}
else
{
File.Delete(@text);
FileStream fs = File.Create*2;
writer = new StreamWriter(fs);
}
writer.WriteLine("P2");
writer.WriteLine(str[1]);
writer.WriteLine("255");
for (int i = 0; i < range_int[0]; i++)
{
for (int v = 0; v < range_int[1]; v++)
{
writer.Write(blwh[i,v]);
if(v == range_int[1] - 1)
{
writer.Write("\n");
break;
}
writer.Write(" ");
}
}
writer.Close();
System.IO.File.Move(@"./b.txt", @"./b.pgm");
}
}
}
}