画像フォーマットの形式についてと、
カラー画像からグレー画像への変換方法、
2値による疑似グレースケール表現(ディザ法と誤差拡散法)、
画像の多値化(減色処理)について、
どれか1つだけでもいいんでプログラムが作成できる程度の詳しさでの説明をお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

1つだけでもいいということなので、簡単なのを答えさせてもらいます。



>カラー画像からグレー画像への変換方法、

grey_image[x][y]
= (color_image[x][y].r + color_image[x][y].g + color_image[x][y].b)/3;

単純に RGB の値を足して 3 で割ってます。

> 画像の多値化(減色処理)について、

多値化と減色は逆のような気がするのですが、減色の方だけ書きます。
256階調のグレースケールを例にしています。

grey_image_[x][y]
= grey_image[x][y]&0xF0;

下位4bitを捨てて16階調にしています。
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QC++とC#

C,C++と進みC#
Visual C#がありますが
C++とC#の違いを教えてください.
C++とJAVAをたしたようなもの
なのでしょうか?

Aベストアンサー

文法/構文上の類似点は多々ありますが、「別物」です。
その相違について掲示板で列挙できるものではありません。
# 本を読んでください。

Qグレースケール画像の画素値を得る

OpenCVを使わずにC言語で、グレースケール画像を読み込んで、各画素をそれに対応する配列に格納するプログラムを作りたいと思っています。
しかし、C言語で画像を読み込む方法や、各画素の画素値を得る方法がわかりません。どなたかご存知の方がいらしたら、教えてください。宜しくお願いします。

Aベストアンサー

グレースケール画像と言っても、フォーマット(内部のデータ形式)が
なんなのかわからないと、読み込みアルゴリズムが考えられません。


jpegの様な、圧縮が入っているフォーマットだと、非常に面倒です。
http://www14.ocn.ne.jp/~setsuki/ext/jpg.htm

逆に、pgmのように画素値をそのままバイナリかアスキーで
書き込んでいるだけなら、freadして配列に格納していくだけです。
画素値が知りたい場合は、配列の場所を指定してfprintでもすればよいでしょう。
http://www.not-enough.org/abe/manual/command/netpbm/pgm.html


方針としては、以下の二つが考えられます。

1.プログラムが対応する画像フォーマット種類を決め、
  そのフォーマットを調べ、対応アルゴリズムを構築する

2.pgmフォーマット読み込みプログラムを作成する。
  別途、画像変換ソフトを用意し、どんな画像でもpgmに変換してから
  プログラムで使用する。

画像変換ソフト例:IrfanView
http://www.forest.impress.co.jp/lib/pic/piccam/picviewer/irfanviewjp.html
画像を読み込んで、名前を付けて保存->pgmで保存


以上、参考になれば幸いです。

グレースケール画像と言っても、フォーマット(内部のデータ形式)が
なんなのかわからないと、読み込みアルゴリズムが考えられません。


jpegの様な、圧縮が入っているフォーマットだと、非常に面倒です。
http://www14.ocn.ne.jp/~setsuki/ext/jpg.htm

逆に、pgmのように画素値をそのままバイナリかアスキーで
書き込んでいるだけなら、freadして配列に格納していくだけです。
画素値が知りたい場合は、配列の場所を指定してfprintでもすればよいでしょう。
http://www.not-enough.org/abe/manual/com...続きを読む

QC#とC++/CLIの連携について

C#とC++/CLIの連携について
C++/CLI側にC#で作成した変数を渡したいのですが、やり方がわかりません。

そもそも一つのソリューションにC++/CLIとC#を混在することはできるのでしょうか。
やはりC++/CLI側はDLLにして、C#がそのDLLを利用するのでしょうか。

Aベストアンサー

.NETの各種言語は混在することができます。
たとえば、C#でGUIの設計をし.NET用DLLを作成し、内部処理をC++でWin32APIを使って書き、C++/CLIでラップして、GUIと結び付ける、とかもできます。

「変数を渡す」というのが表現として良く分かりませんが、変数というよりはクラスを共有する感じになるかと思います。

とはいえC++/CLIはネイティブコードとマネージドコードを混ぜれるがゆえに、逆に色々と問題があるので、ちゃんとネットや本で調べたほうが良いかと思います。

Qグレースケール時の画素値の順番について

グレースケール時の画素値の順番について

今VC++でOpenCVを使ってプログラムを作っています。

白黒のシルエット写真(.bmp)をcvLoadImageでグレースケール画像の8bit1チャンネルとして読み込んでいます。
↓↓
IplImage* p = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);


このpのピクセルごとの画素値を手に入れたいのですが、
IplImageではグレースケール時にはどのような並びで入っているのでしょうか?
3チャンネルならBGRの順で格納されているのはわかるんですが、
1チャンネルの時はそのままポインタがずれれば、次のピクセルという風にシンプルになっているのでしょうか?

今のところポインタを1つずらしたところを隣のピクセルという風に処理をしているんですが、
取り出した値を見ても負の値が出てきているので、たぶん間違いなのでしょう。

どなたか知恵をお貸しください。

Aベストアンサー

CV_LOAD_IMAGE_GRAYSCALEで読みこんだのなら、1 チャンネルのデータになっているはずです。

http://opencv.jp/opencv-2svn/c/basic_structures.html#iplimage
念のため、 p->nChannels の値を確認してください。1になっているはずです。



> 今のところポインタを1つずらしたところを隣のピクセルという風に処理をしているんですが、
> 取り出した値を見ても負の値が出てきているので、たぶん間違いなのでしょう。

IplImage.imageData は char *型(つまり、符号付きchar型)なので、 128~255は -128~-1になります。
unsigned char dc = p->imageData[ y * p->widthStep + x] ;
int dsi = 0xff & (p->imageData[ y * p->widthStep + x] ) ;
など、符号無し型やより大きい型の下位ビットにするようにする必要があります。

QC++ C# 語源

C++とC#(C++++)はかなり大雑把に言うとCの拡張版ですが、なぜ+が二個単位なのでしょうか。
C → C++ → C#
C+とC+++は存在しないのでしょうか。
C → C+ → C++ → C+++ → C#
もし存在しないのであれば、どのような理由でそうなったのでしょうか。

Aベストアンサー

C/C++のインクリメント演算子が、++だからじゃないでしょうか。

Q誤差拡散法のプログラミング

はじめまして。プログラミング課題でグレースケール画像の誤差拡散法を用いた二値化をプログラミングしています。
しかし、書いてあるとおりにプログラミングしても真っ白になってしまいます。どうしてでしょうか?
主なソースコードは

対象画素の画素値:f
誤差:e
-----------------------------------------
for(i = 0 ; i < wide ; i++){
for(j = 0 ; j < high ; j++){
e = f[i][j] - 255;

if(f[i][j] > 127)
f[i][j] = 255;

else
f[i][j] = 0;

f[i+1] += 5/16*e;
f[i+1][j+1] += 3/16*e;
f[i][j+1] += 5/16*e;
}
}
-----------------------------------
というとても簡素な構造になっています。右端とか下とかの場合分けは今省略させてもらいました。
私の考察としてどんどん誤差が累積されるので真っ白になってもおかしくないと思うのですが。教科書やネットページを見てもこのようになっている感じがします。どこがおかしいのか教えてください。よろしくお願いします。

はじめまして。プログラミング課題でグレースケール画像の誤差拡散法を用いた二値化をプログラミングしています。
しかし、書いてあるとおりにプログラミングしても真っ白になってしまいます。どうしてでしょうか?
主なソースコードは

対象画素の画素値:f
誤差:e
-----------------------------------------
for(i = 0 ; i < wide ; i++){
for(j = 0 ; j < high ; j++){
e = f[i][j] - 255;

if(f[i][j] > 127)
f[i][j] = 255;

else
f[...続きを読む

Aベストアンサー

#3です。
アルゴリズム間違ってませんか?
【二値化 誤差拡散法】で検索かけたら
「Floyd & Steinberg型」と「Javis,Judice,& Ninke型」というのが見つかりました。
そこのサンプルと比較すると、
・誤差の計算方法
・誤差の分散方法
が提示したソースと異なっているようです。

QC#でできてC++でできないことは?(C#のメリットとは?)

これから新しい言語として、C#もしくはC++の勉強をしたいと
考えています。

C#にできてC++にできないこと、あるいはその逆でC++にはできて
C#ではできない。ということがあれば、教えていただけないでしょうか?

感覚としてはC++であれば何でもできるという感じではあるのですが、
C#を使うメリットってどんなことがありますか?
やはり、ビジュアル開発(コントロールのDrag&Dropで画面開発ができる)
の簡単さというところがC#でのメリットでしょうか?

ちなみに私はこれまで、C -> VB -> Java といった順で言語を習得
してきました。

Aベストアンサー

>C#にできてC++にできないこと
無いでしょう。
基本的にC/C++の場合コンパイラの種類に依りますが
内部にアセンブラを書くこともできますから
C/C++で出来ないことはC#でも出来ません。
(勿論#1さんの言われるように言語レベルの仕様で出来ない事はあります。)

簡単さでいうとC#です。VB6の開発経験があるとのことですが
VC#だとVBのフォームを作成するような感じでインターフェースを
作っていけます。(一応VC++でも可能)

一方C#で出来ないことですが
当然ですがフレームワークに依存しないソフトを作る事が出来ません。
Javaで作ったソフトがJREを必要とするのと同じです。
他にはCPUの特殊な命令(SSEやMMX)を呼び出すとかドライバの開発等も出来ません。

ちなみにVC++でもフレームワークは使えるので
フレームワークのガベージコレクション等を使うことは可能です。
(ただフレームワークを使うならC#の方が簡単です。)

Q組織的ディザ法のプログラムがうまくいきません

下記のプログラムはPGM画像に組織的ディザ法を行い、2値化を行うプログラムなのですがうまく作動しません。
どこがダメなのかわかる方回答お願いします。

また、PGMのフォーマットをP5しか読み込むことしか出来ないのですが、これを
P2のアスキーで読み込めるように変更できないでしょうか?




/* 組織的ディザ法のプログラム dither.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"mypgm.h"
#define BLOCK_SIZE 4 /* ブロックの横(=縦)画素数 */
#define NEW_LEVEL 16 /* 擬似階調数(= BLOCK_SIZE の2乗) */
#define MAXWIDTH 1000
#define MAXHEIGHT 1000

/* 原画像 image1[y][x] のディザ画像を作り image2[y][x] に代入 */
void make_dither_image( )
{
double width; /* 16段階画像の階調値の単位幅 */
int x,y,i,j,m,n;
int x_block = x_size1 / BLOCK_SIZE; /* 横のブロック数 */
int y_block = y_size1 / BLOCK_SIZE; /* 縦のブロック数 */
int gray_16 = (int)( image1[y][x] / width ); /* 新しい階調(16階調での値) */

/* Bayer 型ディザ行列 */
int dither_matrix [4][4] = {
{ 0, 8, 2, 10},
{12, 4, 14, 6},
{ 3, 11, 1, 9},
{15, 7, 13, 5}
};

/* 横,縦の画素数がBLOCK_SIZEの倍数であるかのチェック */
if ( x_size1 % BLOCK_SIZE != 0 || y_size1 % BLOCK_SIZE != 0 ){
printf("原画像の横・縦の画素数が不適切です.\n");
exit(1);
}

/* 16階調の画像を作る */ //一度、画像を16階調に変換して(正確にはディザブロック分の1)さらに2階調(白黒)に変換する。
width = MAX_BRIGHTNESS / (double)NEW_LEVEL;
x_size2 = x_size1; y_size2 = y_size1;
for (y = 0; y < y_size1; y ++ ){
for (x = 0; x < x_size1; x ++ ){
if ( gray_16 > NEW_LEVEL - 1 ) gray_16 = NEW_LEVEL - 1;
image2[y][x] = (unsigned char)gray_16;
}
}

/* ディザ画像を作る */
printf("ディザ画像を作ります.\n");
for (i = 0; i < y_block; i ++ ){
for (j = 0; j < x_block; j ++ ){
int x = BLOCK_SIZE * j;
int y = BLOCK_SIZE * i;
for (m = 0; m < BLOCK_SIZE; m ++ ){
for (n = 0; n < BLOCK_SIZE; n ++ ){
if ( image2[y + m][x + n] <= dither_matrix[m][n] ) image2[y + m][x + n] = 0;
else image2[y + m][x + n] = MAX_BRIGHTNESS;
}
}
}
}

}


【mypgm.h】
http://cis.k.hosei.ac.jp/~wakahara/mypgm.h

下記のプログラムはPGM画像に組織的ディザ法を行い、2値化を行うプログラムなのですがうまく作動しません。
どこがダメなのかわかる方回答お願いします。

また、PGMのフォーマットをP5しか読み込むことしか出来ないのですが、これを
P2のアスキーで読み込めるように変更できないでしょうか?




/* 組織的ディザ法のプログラム dither.c */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"mypgm.h"
#define BLOCK_SIZE 4 /* ブロックの横(=縦)画素数 */
#define ...続きを読む

Aベストアンサー

P2形式のPGMに対応したいのであれば、画像読み込みルーチンの方をP2に対応させる必要がありますが、
今回挙げられているディザ処理そのものは、今のままでまったく問題はありません。

画像読み込み部の対応ですが、ヘッダ部はP5もP2も同じです。
実データ読み取り部で、P2だった時は fgetc の代わりに、
---
int value;
fscanf(fp, "%d", &value);
image[y][x] = value;
---
といったコードにするだけでいけます。

あと、今回の質問とは直接関係ありませんが、
4×4のディザの階調数は16ではなく17です。(「1が0個」~「1が16個」の17通り)
今のコードだと、一番明るい白が輝度値15にしていますが、15の時は4x4の左下が0になってしまい、全面白ではなく、黒の点が出てきます

QC#でCのコンソール出力の取得

C#でCのコンソール出力の取得
Cで作成したDLLをC#で利用しています。このときDLLファイルはC言語のprintfを使用しています。この出力内容を取得して、C#でテキストボックス等に表示する方法はありませんでしょうか。

Aベストアンサー

使ったこと無いのですが
Googleで調べたところ以下のWebページがヒットしました。

@IT
.NET TIPS
コンソール・アプリケーションの出力を取り込むには?[C#、VB]
http://www.atmarkit.co.jp/fdotnet/dotnettips/657redirectstdout/redirectstdout.html

参考URL:http://www.atmarkit.co.jp/fdotnet/dotnettips/657redirectstdout/redirectstdout.html

Q画像解析 ライン認識 2値化 2値化

開発言語は、アルゴリズムができてから最善のものを使いたいと思ってますが、現状はVisualC++です。

トイレットペーパーの芯や、キッチンペーパーの芯を平べったく伸ばした感じの紙媒体を、デジタルカメラで撮影した画像から、その芯のラインの本数、ライン1本毎の幅、ラインのエッジ出力、ライン以外の黒い要素(ゴミやノイズになる部分)・・・などを求めれるアルゴリズムを考案しています。

この際に、ラインを認識することが第1条件で、2値化したときにゴミとなる点の集合と、ライン要素になる点の集合を区別し、ラベリング処理でライン番号を付けれたら・・・っと考えてます。

ただ、困ったことにカメラや照明の制度が悪く、濃淡が激しい画像になってます。あと、左右に大きな余白(実際には黒色)ができたり、余白とライン要素の交点部分「余白(ト)ライン」みたいな箇所で、余白なのかラインなのか区別ができない状態です。

また、2値化した際に、
□□□□□■■■□□□□□□□□□
□□□□□□■■■□□□□□□□□
□□□□□□□■■■■■■□□□□
□□□□□□□□■■■□□■■□□
□□□□□□□□■■■□□□■■□
□□□□□□□□□■■■□□□□□
このようなゴミがくっついている場合や、ラインの途中が薄い部分が白と認識され、上のように分裂してしまったり・・・。

VC++6.0で、読み込んだビットマップの数値データをCSVに保存するところまで、できている状態です。(0~255の数字が出力されてます)

開発言語は、アルゴリズムができてから最善のものを使いたいと思ってますが、現状はVisualC++です。

トイレットペーパーの芯や、キッチンペーパーの芯を平べったく伸ばした感じの紙媒体を、デジタルカメラで撮影した画像から、その芯のラインの本数、ライン1本毎の幅、ラインのエッジ出力、ライン以外の黒い要素(ゴミやノイズになる部分)・・・などを求めれるアルゴリズムを考案しています。

この際に、ラインを認識することが第1条件で、2値化したときにゴミとなる点の集合と、ライン要素になる点の集...続きを読む

Aベストアンサー

Hough変換はご存じでしょうか?
Hough変換で直線成分を抽出して,長ければライン,短ければゴミ,ある程度長くて,同じ延長線上にあるなら同一のラインとして扱う,等すると良いのでは.
試すだけならC(C++)&OpenCVが楽です.
・OpenCV -Hough変換-
http://opencv.jp/sample/special_transforms.html
・OpenCV チュートリアル
http://chihara.naist.jp/opencv/?FrontPage

> ただ、困ったことにカメラや照明の制度が悪く、濃淡が激しい画像になってます。
> あと、左右に大きな余白(実際には黒色)ができたり、余白とライン要素の交点部分「余白(ト)ライン」みたいな箇所で、余白なのかラインなのか区別ができない状態です。

この辺はまた別問題の様な気がします.
まずは,機材の変更・環境の変更・撮影方法の変更・手動の前処理を入れる,などで解決すべきところではないでしょうか.
> 余白の黒色
古典的手法で,ブルーバックにしてみるとか?

まあ,大学の画像処理研究なのか,実際の既存工場のラインで使用するのとでは,このあたり違ってきてしまうとは思います.
(アルゴリズムの研究なら,本筋でない要素は事前排除すべきでしょうし,お仕事の実用ソフトならそうも言ってられないでしょうし...)

Hough変換はご存じでしょうか?
Hough変換で直線成分を抽出して,長ければライン,短ければゴミ,ある程度長くて,同じ延長線上にあるなら同一のラインとして扱う,等すると良いのでは.
試すだけならC(C++)&OpenCVが楽です.
・OpenCV -Hough変換-
http://opencv.jp/sample/special_transforms.html
・OpenCV チュートリアル
http://chihara.naist.jp/opencv/?FrontPage

> ただ、困ったことにカメラや照明の制度が悪く、濃淡が激しい画像になってます。
> あと、左右に大きな余白(実際には黒色)が...続きを読む


人気Q&Aランキング

おすすめ情報