質問編集履歴
9
質問の修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -2,10 +2,8 @@
|
|
2
2
|
|
3
3
|
やりたいこととしては以下URLの内容の、__固定パレット(24bit→8bit (245 color))+誤差拡散(Floyd-Steinberg)__、もしくは__最適化パレット(24bit→8bit)+誤差拡散(Floyd-Steinberg)__で行いたいと考えています。
|
4
4
|
ただし、色数は255ではなく**254**です。
|
5
|
-
サイトではメディアン・カット(中央値分割)と書かれているものです。
|
6
5
|
|
7
6
|
現状はとにかく減色させて8bitにと思って、OpenCvSharp3のCv2.Kmeansによる減色を試みたのですが、減色はできても8bitにはできずにてこずっております。
|
8
|
-
さらに、どこのサイトだったかは分からなくなったのですが、Kmeansは処理負荷が高いので、その前に一度メディアン・カットを行ってからのほうがいいとあったので、それもメディアンカットで実施したい理由です。
|
9
7
|
|
10
8
|
環境:WindowsForms
|
11
9
|
URL:[http://koujinz.cocolog-nifty.com/blog/2009/04/24bit-8bit-a879.html](http://koujinz.cocolog-nifty.com/blog/2009/04/24bit-8bit-a879.html
|
@@ -102,7 +100,7 @@
|
|
102
100
|
|
103
101
|
追記1>
|
104
102
|
要件:
|
105
|
-
・メディアンカットでの減色を行いたい(記載しているのはKmeans)
|
103
|
+
・~~メディアンカットでの減色を行いたい(記載しているのはKmeans)~~
|
106
104
|
・24bit→8bit(254色)に変換したい
|
107
105
|
・上記に関するライブラリ、参考サイト、コードがあれば
|
108
106
|
|
@@ -181,4 +179,9 @@
|
|
181
179
|
|
182
180
|
return bmpSource;
|
183
181
|
}
|
184
|
-
```
|
182
|
+
```
|
183
|
+
|
184
|
+
|
185
|
+
追記:
|
186
|
+
メディアンカットは本要件と違ったため、その部分を削除しました。
|
187
|
+
また追記部分には取り消し線で対応しました。
|
8
サンプル修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -124,6 +124,8 @@
|
|
124
124
|
|
125
125
|
unsafe static Bitmap ImageConvert24biTo8bit(Bitmap bmpSource)
|
126
126
|
{
|
127
|
+
int pixelSize = 4;
|
128
|
+
int color = 255;
|
127
129
|
|
128
130
|
//入力されたBitmapをロック
|
129
131
|
BitmapData bmpData = bmpSource.LockBits(
|
@@ -144,11 +146,15 @@
|
|
144
146
|
// Bitmapオブジェクトを作成
|
145
147
|
Bitmap bmp8bit = new Bitmap(bmpSource.Width, bmpSource.Height, PixelFormat.Format8bppIndexed);
|
146
148
|
|
149
|
+
// カラーパレットを設定
|
150
|
+
ColorPalette pal = bmp8bit.Palette;
|
151
|
+
|
147
152
|
for (int y = 0; y < bmpData.Height; y++)
|
148
153
|
{
|
149
154
|
for (int x = 0; x < bmpData.Width; x++)
|
150
155
|
{
|
151
|
-
/
|
156
|
+
/*① この辺りが?です */
|
157
|
+
|
152
158
|
//(x,y)のデータ位置
|
153
159
|
int pos = y * bmpData.Height + x * pixelSize;
|
154
160
|
|
@@ -158,10 +164,18 @@
|
|
158
164
|
byte r = pixels[pos + 2];
|
159
165
|
|
160
166
|
// 色
|
167
|
+
for (int i = 0; i < color; ++i)
|
168
|
+
{
|
161
|
-
|
169
|
+
pal.Entries[i] = Color.FromArgb(255, r, g, b);
|
170
|
+
}
|
171
|
+
bmpSource.Palette = pal;
|
162
172
|
}
|
163
173
|
}
|
164
174
|
|
175
|
+
|
176
|
+
// 変更を反映
|
177
|
+
Marshal.Copy(pixels, 0, pointer, pixels.Length);
|
178
|
+
|
165
179
|
//ロックを解除する
|
166
180
|
bmpSource.UnlockBits(bmpData);
|
167
181
|
|
7
微々たる誤記の修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -107,6 +107,7 @@
|
|
107
107
|
・上記に関するライブラリ、参考サイト、コードがあれば
|
108
108
|
|
109
109
|
現状:
|
110
|
+
メディアンカットでは進展なし。
|
110
111
|
24bit→8bit変換でサンプルを作成中。
|
111
112
|
|
112
113
|
追記2>
|
6
サンプル修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -148,18 +148,16 @@
|
|
148
148
|
for (int x = 0; x < bmpData.Width; x++)
|
149
149
|
{
|
150
150
|
//①この辺りが今?です
|
151
|
-
if(pixels[y * x] <= 85)
|
152
|
-
{
|
153
|
-
|
151
|
+
//(x,y)のデータ位置
|
154
|
-
}
|
155
|
-
|
152
|
+
int pos = y * bmpData.Height + x * pixelSize;
|
156
|
-
{
|
157
153
|
|
158
|
-
|
154
|
+
// RGB
|
155
|
+
byte b = pixels[pos];
|
159
|
-
|
156
|
+
byte g = pixels[pos + 1];
|
160
|
-
|
157
|
+
byte r = pixels[pos + 2];
|
161
158
|
|
162
|
-
|
159
|
+
// 色
|
160
|
+
Color col = Color.FromArgb(255, r, g, b);
|
163
161
|
}
|
164
162
|
}
|
165
163
|
|
5
誤記修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -148,15 +148,15 @@
|
|
148
148
|
for (int x = 0; x < bmpData.Width; x++)
|
149
149
|
{
|
150
150
|
//①この辺りが今?です
|
151
|
-
if(pixels[x] <= 85)
|
151
|
+
if(pixels[y * x] <= 85)
|
152
152
|
{
|
153
153
|
//
|
154
154
|
}
|
155
|
-
else if(pixels[x] <= 170)
|
155
|
+
else if(pixels[y * x] <= 170)
|
156
156
|
{
|
157
157
|
|
158
158
|
}
|
159
|
-
else if (pixels[x] <= 255)
|
159
|
+
else if (pixels[y * x] <= 255)
|
160
160
|
{
|
161
161
|
|
162
162
|
}
|
4
サンプル(未完成)のコードを掲載
title
CHANGED
File without changes
|
body
CHANGED
@@ -100,11 +100,72 @@
|
|
100
100
|
}
|
101
101
|
```
|
102
102
|
|
103
|
-
追記>
|
103
|
+
追記1>
|
104
104
|
要件:
|
105
105
|
・メディアンカットでの減色を行いたい(記載しているのはKmeans)
|
106
106
|
・24bit→8bit(254色)に変換したい
|
107
107
|
・上記に関するライブラリ、参考サイト、コードがあれば
|
108
108
|
|
109
109
|
現状:
|
110
|
-
24bit→8bit変換でサンプルを作成中。
|
110
|
+
24bit→8bit変換でサンプルを作成中。
|
111
|
+
|
112
|
+
追記2>
|
113
|
+
サンプルとして、以下のところまで作成。
|
114
|
+
|
115
|
+
>NotionalKettleさん
|
116
|
+
>つまり減色された画像データに含まれるRGBの組とそれに対応する値(8bit用)を定義して対応が付けられるように8bit側の各画素を上記の方法>で書き換えて、最後にパレットを対応させれば・・・
|
117
|
+
|
118
|
+
この部分でどうすればいいのかイメージがつかずに詰まってます。
|
119
|
+
下記コードではコメント①あたりです。
|
120
|
+
尚、byte*での方法については理解が追い付いていないので、とりあえずMarshal.Copyで試してます。
|
121
|
+
|
122
|
+
```C#
|
123
|
+
|
124
|
+
unsafe static Bitmap ImageConvert24biTo8bit(Bitmap bmpSource)
|
125
|
+
{
|
126
|
+
|
127
|
+
//入力されたBitmapをロック
|
128
|
+
BitmapData bmpData = bmpSource.LockBits(
|
129
|
+
new Rectangle(0, 0, bmpSource.Width, bmpSource.Height),
|
130
|
+
ImageLockMode.WriteOnly,
|
131
|
+
bmpSource.PixelFormat
|
132
|
+
);
|
133
|
+
|
134
|
+
//Bitmapの各画素情報のbyte配列データの先頭ポインタ
|
135
|
+
IntPtr pointer = bmpData.Scan0;
|
136
|
+
//byte* pImg = (byte*)bmpData.Scan0.ToPointer();
|
137
|
+
|
138
|
+
byte[] pixels = new byte[bmpData.Stride * bmpSource.Height];
|
139
|
+
|
140
|
+
// Bitmap を byte [ ] へコピー
|
141
|
+
Marshal.Copy(pointer, pixels, 0, pixels.Length);
|
142
|
+
|
143
|
+
// Bitmapオブジェクトを作成
|
144
|
+
Bitmap bmp8bit = new Bitmap(bmpSource.Width, bmpSource.Height, PixelFormat.Format8bppIndexed);
|
145
|
+
|
146
|
+
for (int y = 0; y < bmpData.Height; y++)
|
147
|
+
{
|
148
|
+
for (int x = 0; x < bmpData.Width; x++)
|
149
|
+
{
|
150
|
+
//①この辺りが今?です
|
151
|
+
if(pixels[x] <= 85)
|
152
|
+
{
|
153
|
+
//
|
154
|
+
}
|
155
|
+
else if(pixels[x] <= 170)
|
156
|
+
{
|
157
|
+
|
158
|
+
}
|
159
|
+
else if (pixels[x] <= 255)
|
160
|
+
{
|
161
|
+
|
162
|
+
}
|
163
|
+
}
|
164
|
+
}
|
165
|
+
|
166
|
+
//ロックを解除する
|
167
|
+
bmpSource.UnlockBits(bmpData);
|
168
|
+
|
169
|
+
return bmpSource;
|
170
|
+
}
|
171
|
+
```
|
3
誤記修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -102,7 +102,7 @@
|
|
102
102
|
|
103
103
|
追記>
|
104
104
|
要件:
|
105
|
-
・メディアンカットでの減色を行いたい
|
105
|
+
・メディアンカットでの減色を行いたい(記載しているのはKmeans)
|
106
106
|
・24bit→8bit(254色)に変換したい
|
107
107
|
・上記に関するライブラリ、参考サイト、コードがあれば
|
108
108
|
|
2
要件と現状を追記。その他内容に影響しない微細な誤記を修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
24bit の画像を 8bit (
|
1
|
+
24bit の画像を 8bit (**254** **color**) にする方法についてわからなくて困っております。
|
2
2
|
|
3
3
|
やりたいこととしては以下URLの内容の、__固定パレット(24bit→8bit (245 color))+誤差拡散(Floyd-Steinberg)__、もしくは__最適化パレット(24bit→8bit)+誤差拡散(Floyd-Steinberg)__で行いたいと考えています。
|
4
4
|
ただし、色数は255ではなく**254**です。
|
@@ -98,4 +98,13 @@
|
|
98
98
|
}
|
99
99
|
|
100
100
|
}
|
101
|
-
```
|
101
|
+
```
|
102
|
+
|
103
|
+
追記>
|
104
|
+
要件:
|
105
|
+
・メディアンカットでの減色を行いたい
|
106
|
+
・24bit→8bit(254色)に変換したい
|
107
|
+
・上記に関するライブラリ、参考サイト、コードがあれば
|
108
|
+
|
109
|
+
現状:
|
110
|
+
24bit→8bit変換でサンプルを作成中。
|
1
誤記修正
title
CHANGED
File without changes
|
body
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
環境:WindowsForms
|
11
11
|
URL:[http://koujinz.cocolog-nifty.com/blog/2009/04/24bit-8bit-a879.html](http://koujinz.cocolog-nifty.com/blog/2009/04/24bit-8bit-a879.html
|
12
12
|
|
13
|
-
尚、単純に以下の
|
13
|
+
尚、単純に以下のCloneでPixelFormat.Format8bppIndexedを指定した場合、8bitにはできるものの、色数254の前に画質が荒すぎて酷かったので止めました。
|
14
14
|
```C#
|
15
15
|
Bitmap dstBmp = ImageToBmp.Clone(new Rectangle(0, 0, ImageToBmp.Width, ImageToBmp.Height), PixelFormat.Format8bppIndexed);
|
16
16
|
```
|
@@ -31,9 +31,9 @@
|
|
31
31
|
/// <summary>
|
32
32
|
/// Kmeans法による減色
|
33
33
|
/// </summary>
|
34
|
-
/// <param name="input"></param>
|
34
|
+
/// <param name="input">入力画像</param>
|
35
|
-
/// <param name="result"></param>
|
35
|
+
/// <param name="result">減色結果画像</param>
|
36
|
-
/// <param name="ClusterCount"></param>
|
36
|
+
/// <param name="ClusterCount">クラスター値</param>
|
37
37
|
public static void Kmeans(Mat input, Mat result, int ClusterCount)
|
38
38
|
{
|
39
39
|
using (Mat points = new Mat())
|