マルシェル新規登録で5000円分当たる

画像処理に関する質問です。初歩的なことかもしれませんが、ご教授お願いいたします。
開発環境はVisual C++ 2005です。

JPEGまたはBMP画像を読み込んで、その画像のピクセル値を表示するプログラムを作成したいのですが、まったくどうしてよいか判らず、行き詰っています。

これまでいろいろ試してみたのですが、読み込んだ画像をBit値に変換してしまったり(そのせいでパソコンがクラッシュしてしまいました…)、うまくいきません。

画像処理の対象となる原画像を取り込み、その原画像のピクセルの色情報を表示するためには、どのような処理を行えばよいのでしょうか?

どうぞよろしくお願いします。

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

A 回答 (2件)

MFCが使える環境なら CImageクラスで処理する


MFCが使えないなら GDI+で処理する
この場合Bitmapクラスに読み込んで GetPiixelなどを使えば出来そうです
GDI+は 専用の初期化コマンドなどがありますので 詳細はヘルプのGDI+関連を参照してみましょう
    • good
    • 0

こんにちは。


画像処理って、初心者が手を出すネタとしてはありがちなのですが、
実は意外と奥が深くて面倒だったりします。

とりあえず、フォーマットを無圧縮のBMPのみに限定するなら、ファイル全体をバイナリファイルとしてメモリに取り込んで処理するのが簡単です。
BMPファイルのフォーマットは、BITMAPFILEHEADERとBITMAPINFOについてヘルプを引いてみればわかると思います。

jepgに対応するなら、LoadImageでDIBSectionで取り出すのが楽かなと思いますが、その場合でも、上記BITMAPINFO等の知識が必要ですので、まずは上記の方法で、無圧縮BMPファイルのみを対象としてプログラムを組んでみることをおすすめします。
    • good
    • 0

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

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

このQ&Aを見た人はこんなQ&Aも見ています

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

このQ&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...続きを読む

Q画素値取得について

質問ですがCやC++で画素値を取得するにはどうしたらいいでしょうか

Aベストアンサー

それ以外ってどのOSでしょうか。
C/C++は標準で画像を扱うライブラリなんてありませんよ?
OSに依存します。

bmpやjpegのファイルならフォーマットが決まっているので
ファイルをバイナリでオープンしてデータを取得します。

参考URL:http://www.kk.iij4u.or.jp/~kondo/bmp/

Q画像の輝度値のプログラムについて・・・・・・

プログラムをPCでやる前にある程度、何かに書いてからやっているのですが、画像の1部分の色を変えたいのですが、例えば画像の左半分を黒くした画像を生成したい場合は,(一般的には,輝度値は0~255までの整数(8ビット)か,または0~65535までの整数(16ビット)により表される)


*printfとscanfを使用するためにインクルードする*/
#include<stdio.h>
/*ビットマップ画像を扱うためのヘッダ*/
#include<Dll_BMP_C.h>

//画像ファイル名最大長(バイト)
#define NAME_SIZE 101

int main(void)
{
int j,k;
/* nWidth:画像の幅、nHeight:画像の高さ、nVal:輝度値*/
int nWidth,nHeight;
/*pcFileName:画像ファイル名を保存する配列*/
char pcFileName[NAME_SIZE];
/*pBmpOrig:読み込んだ画像へのポインタ
pBmpCopy:複製した画像へのポインタ*/
DllBmp*pBmpOrig,*pBmpCopy;

/*読み込む画像のファイル名を指定する*/
printf(“読み込む画像”);
scanf(“%s”,pcFileName);


/*画像を読み込みメモリに保存する
読み込みに失敗したら実行を中止する*/
pBmpOrig=DllBmpReadImage(pcFileName);
if(pBmpOrig==NULL)
{
printf(“画像の読み込みに失敗! 実行を中止します\n”);
exit(1);
}

/*読み込んだ画像のヘッダ情報を表示する*/
DllBmpShowHeader(pBmpOrig);

/*読み込んだ画像の大きさを得る*/
nWidth=DllBmpGetWidth(pBmpOrig);
nHeight= DllBmpGetHeight (pBmpOrig);

/* 画像を生成する */
 for(j = 0; j < nHeight; j++)
  for(k = 0; k < nWidth; k++)
   {
    DllBmpSetPixelValueR(pBmpOrig, j, k, 255);
    DllBmpSetPixelValueG(pBmpOrig, j, k, 255);
    DllBmpSetPixelValueB(pBmpOrig, j, k, 255);
   }


/*保存する画像のファイル名を指定する*/
printf(“保存する画像”);
scanf(“%s”,pcFileName);

/*画像を保存する
保存に失敗したら実行を中止する*/
if(!DllBmpWriteImage(pcFileName,pBmpOrig));
{
printf(“画像の保存に失敗! 実行に中止します”);
exit(1);
}

/*画像をメモリから消去する*/
DllBmpDleteImage(pBmpOrig);

return 0;

}

画像の輝度値を操作するプログラムをやっているのですが、画像の左半分を黒くした画像を生成する場合は、
DllBmpSetPixelValueR(pBmpOrig, j, k, 255);
DllBmpSetPixelValueG(pBmpOrig, j, k, 255);
DllBmpSetPixelValueB(pBmpOrig, j, k, 255);
の部分のRが赤、Gが緑、Bが青なんですが、その値をすべて0にすればいいんでしょうか?もしくはあらたに条件式を作るべきなのでしょうか??そして画像の左半分を黒くしたい場合は、
for(j = 0; j < nHeight; j++)
  for(k = 0; k < nWidth; k++)
の部分のj < nHeightをj < nHeight/2にしたらなるでしょうか??
この場合だと上半分になってしまうでしょうか??
PCがまだ使えないのでルーズリーフにいろいろ試行錯誤して書いてるのですが、他に何かヒントがあればよろしくお願いします。。。。。
すみませんがお願いします。

プログラムをPCでやる前にある程度、何かに書いてからやっているのですが、画像の1部分の色を変えたいのですが、例えば画像の左半分を黒くした画像を生成したい場合は,(一般的には,輝度値は0~255までの整数(8ビット)か,または0~65535までの整数(16ビット)により表される)


*printfとscanfを使用するためにインクルードする*/
#include<stdio.h>
/*ビットマップ画像を扱うためのヘッダ*/
#include<Dll_BMP_C.h>

//画像ファイル名最大長(バイト)
#define NAME_SIZE 101

int main(void)
{
int j,k...続きを読む

Aベストアンサー

>>j < nHeightをj < nHeight/2にしたらなるでしょうか??
 この場合だと上半分になってしまうでしょうか??
 はい。左半分の場合はnWidth/2のハズです

一応参考と言う事で(過信してはいけません)。

/*幅の半分を計算しておく*/
const int nHalf = nWidth / 2;

/*輝度用の変数*/
int nKido = 0;

for(j = 0; j < nHeight; j++)
  for(k = 0; k < nWidth; k++)
   {
/*kはnWidthの半分以下なら輝度は0、それ以上なら輝度は255*/
nKido = (nHalf <= k) ? 0 : 255;

/*着色?*/
    DllBmpSetPixelValueR(pBmpOrig, j, k, nKido);
    DllBmpSetPixelValueG(pBmpOrig, j, k, nKido);
    DllBmpSetPixelValueB(pBmpOrig, j, k, nKido);
   }

>>j < nHeightをj < nHeight/2にしたらなるでしょうか??
 この場合だと上半分になってしまうでしょうか??
 はい。左半分の場合はnWidth/2のハズです

一応参考と言う事で(過信してはいけません)。

/*幅の半分を計算しておく*/
const int nHalf = nWidth / 2;

/*輝度用の変数*/
int nKido = 0;

for(j = 0; j < nHeight; j++)
  for(k = 0; k < nWidth; k++)
   {
/*kはnWidthの半分以下なら輝度は0、それ以上なら輝度は255*/
nKido = (nHalf <= k) ...続きを読む

Q画像の2値化について

グレー画像を微分ヒストグラムを用いて2値化する方法を教えてください。
プログラムが書ける程度の詳しさでアルゴリズムの説明をお願いします。

Aベストアンサー

・2値化関数(グレー画像と閾値を引数に与えると2値画像を返す)
・閾値決定関数(グレー画像を引数に与えるとヒストグラムの微分値の
        極大値を返す)
というのがあれば実現できるのでは?

2値化関数は簡単ですよね。グレー画像における画素(i,j)における
2値化作業は、輝度値の閾値Θに対して、Ib[j][i] = Ig[j][i] > Θ
を実行すれば良いですよね。ただし、Ib[j][i]は2値画像の画素(i,j)の
値、Ig[j][i]はグレー画像の画素(i,j)の値。不等号演算子は真なら1、
偽なら0を返す。

さて、閾値決定関数ですが、まず、輝度値ごとのヒストグラムを
作ります。

int hist[256]; // グレー画像が256階調であるとする。
for(i = 0 ; i < x_size ; i++)
 for(j = 0 ; j < y_size ; j++)
  hist[Ig[j][i]]++;

次に、ヒストグラムを使って、微分ヒストグラムを作ります。

int dhist[256];
for(i = 0; i < 256 ; i++)
 dhist[i] = hist[i+1] - hist[i];

こんな感じです。後は微分ヒストグラムdhistを最大にする
輝度値を求めればOKです。

離散値の微分は他の方法もあります。例えば、

 dhist[i] = (hist[i+1] - hist[i-1]) / 2.0f;

なんかも。

あと、画像のサイズが十分に大きくないときには、
工夫(画素ヒストグラムが極端に低い・高い画素が
存在し得るので)が必要かも知れません。

・2値化関数(グレー画像と閾値を引数に与えると2値画像を返す)
・閾値決定関数(グレー画像を引数に与えるとヒストグラムの微分値の
        極大値を返す)
というのがあれば実現できるのでは?

2値化関数は簡単ですよね。グレー画像における画素(i,j)における
2値化作業は、輝度値の閾値Θに対して、Ib[j][i] = Ig[j][i] > Θ
を実行すれば良いですよね。ただし、Ib[j][i]は2値画像の画素(i,j)の
値、Ig[j][i]はグレー画像の画素(i,j)の値。不等号演算子は真なら1、
偽なら0を返す...続きを読む

Qビットマップ画像を読み込むプログラムがうまく行きません。困ってます…。

こんにちは。大学4年のyu-tinと申します。
現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。

1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、
 その画像の1つ1つの画素の輝度値を表示させる
2)読み込んだビットマップ画像を出力させる

しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。

a)0行0列~1行383列までの画素値がおかしい。
 (0,0,0,0,1,1,1,0,2,2,2,0,3,3,3,0,…,254,0,255,255,255,0 となっている)
b)出力した画像の最上部2行程度に、細くて黒い線が表示される。
 (読み込んだ画像と全く同じ画像を出力させたい)
c)出力した画像が、”ディスクエラー”によりPhotoshopで開けない。
 (ペイントでは開ける)

その問題のプログラムは、以下の通りです。
しかし、このプログラムは、他人のプログラムに改良を加えて作成したものです。なので、このプログラム自体、私自身が完璧に理解できていない状況です。

私は、プログラミングに関しては初心者に近いので、丁寧に教えて頂けると大変助かります。
研究が先に進まず、大変困っています…。みなさま、本当に、本当によろしくお願い致します。



//ビットマップ画像に関するプログラム。
//画像の表示と輝度値の表示を行う。

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>

#define X_SIZE 640  //画像の横幅(ピクセル数)
#define Y_SIZE 480  //画像の縦幅(ピクセル数)
#define Z_SIZE 1    //1つの画素に含まれる色の数

void *malloc(size_t size);

void main(void)
{
 int i, j, k;   //ループ用変数 i…縦の画素用, j…横の画素用, k…色数用
 int x=0;    //画像の横幅(ピクセル数)*/
 int y=0;     //画像の縦幅(ピクセル数)
 FILE *fp;

/***********元画像データのメモリ確保*********/
 BYTE ***mae;
 mae=(BYTE ***)malloc(sizeof(BYTE **)*Y_SIZE);
 for(i = 0; i < Y_SIZE; i++){
  mae[i]=(BYTE **)malloc(sizeof(BYTE *)*X_SIZE);
 }
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   mae[i][j]=(BYTE *)malloc(sizeof(BYTE)*Z_SIZE);
  }
 }

/*******画像の読み込み・輝度値の表示*******/
 fp=fopen("sample1.bmp","rb");   //画像”sample1”を開く

 BITMAPFILEHEADER bmfh;
 BITMAPINFOHEADER bmih;

 fread(&bmfh,sizeof(bmfh),1,fp);
 fread(&bmih,sizeof(bmih),1,fp);

 x=bmih.biWidth;  //インフォヘッダに含まれる画像の幅情報をxに代入
 y=bmih.biHeight;  //インフォヘッダに含まれる画像の高さ情報をyに代入

 for(i = 0; i < y ;i++){
  for(j = 0; j < x; j++){
   fread(&mae[i][j][0],sizeof(BYTE),1,fp);
   if(i<640 && j<480)printf("%d, %d, %d\n",i, j, mae[i][j][0]);   //輝度値を表示
  }
 }
 fclose(fp);

/**************画像の表示*************/
 //画像”sample1”を”sample2”という名前で出力する
 fp = fopen("sample2.bmp" ,"wb");

 //ヘッダの書き込み
 fwrite(&bmfh,sizeof(bmfh),1,fp);
 fwrite(&bmih,sizeof(bmih),1,fp);

 for(i = 0; i < bmih.biHeight; i++){
  for(j = 0; j < bmih.biWidth; j++){
   fwrite(&mae[i][j][0],sizeof(BYTE),1,fp);
  }
 }
 fclose(fp);  //ファイルをクローズ

}

こんにちは。大学4年のyu-tinと申します。
現在、大学の研究で使用するためのプログラムとして、以下の機能を持ったプログラム作りに取り込んでいます。

1)ビットマップ画像(グレースケール、縦480×横640pixel)を読み込み、
 その画像の1つ1つの画素の輝度値を表示させる
2)読み込んだビットマップ画像を出力させる

しかし、作成したプログラムがうまく行きません。以下の3つの問題が発生しています。

a)0行0列~1行383列までの画素値がおかしい。
 (0,0,0,0,1,1,1,0,2,2,2,0,3...続きを読む

Aベストアンサー

ビットマップファイルにはビット深度が24ビット未満の場合
このファイルで使用されるパレットが登録されています
BITMAPINFOHEADER と 実際のビットイメージの間に
RGBA*何色といったパレットが存在します
グレースケールの8bitなら256個です
何個あるかは BITMAPINFOHEADERのbiClrUsedがそれに当ります
これが0ならbiBitCountをビットシフトして求めます
1 << biBitCountが個数になります
実際のバイトデータとしては
(1 << biBitCount) * sizeof(RGBQ) バイト存在します

したがって
BYTE* pPalette = (BYTE*)calloc( sizeof(RGBQ), (1 << biBitCount) );
とバッファを宣言して

fread(&bmih,sizeof(bmih),1,fp);
の後で
fread( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行してから
色情報を取得しましょう

書き出すときも同じように
fwrite(&bmih,sizeof(bmih),1,fp);
の後で
fwrite( pPalette, sizeof(RGBQ), (1 << biBitCount), fp );
を実行します

あと動的に確保したバッファは使い終わったら free()で開放しましょう

return 0;の前に
 free( pPalette );
 for(i = 0; i < Y_SIZE; i++){
  for(j = 0; j < X_SIZE; j++){
   free(mae[i][j]);
  }
 }
 for(i = 0; i < Y_SIZE; i++){
  free(mae[i]);
 }
 free(mae);
といった具合に 逆順に開放していきます

ビットマップファイルにはビット深度が24ビット未満の場合
このファイルで使用されるパレットが登録されています
BITMAPINFOHEADER と 実際のビットイメージの間に
RGBA*何色といったパレットが存在します
グレースケールの8bitなら256個です
何個あるかは BITMAPINFOHEADERのbiClrUsedがそれに当ります
これが0ならbiBitCountをビットシフトして求めます
1 << biBitCountが個数になります
実際のバイトデータとしては
(1 << biBitCount) * sizeof(RGBQ) バイト存在します

したがって
BYTE* pPalette...続きを読む

QLNK2019: 未解決の外部シンボルのエラーが出る

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自キャラのデータ
Point2D g_jikipos = {40, 400};//自キャラの座標

//画像ハンドル
int g_jikiimage[11];

//色々なファイルの読み込み
int LoadFiles(){
//画像ファイル読み込み
if(LoadDivGraph("media\\player01.bmp",
11,11,1,64,64,g_jikiimage) == -1) return -1;

return 1;
}


 mymain.h
//他から呼び出させるMyMainの関数
void MyMain();
int LoadFiles();


 myhelper.h(サンプルなので打ちミスはない)
#include "DxLib.h"
#include <limits.h>
#include <math.h>

//構造体宣言
//座標またはベクトルを記録する構造体
struct Vector{
float x,y;
};
typedef Vector Point2D;
//線を記録する構造体
struct Line2D{
Point2D startpos, endpos;
float katamuki;//傾きをラジアン値で記録
Vector speed;//移動している場合は速度をセット
};
//球体を記録する構造体
struct Ball2D{
Point2D position;
float hankei;//半径
};
//四角形を記録する構造体
struct Rect2D{
Point2D lefttop;
Point2D rightbottom;
float width;
float height;
};


//ライブラリ関数
Point2D PosInView(Point2D in);
int XInView(float inx);
int YInView(float iny);
void ScrollToLeft(float jikiposx);
void ScrollToRight(float jikiposx);
void ScrollToUp(float jikiposy);
void ScrollToDown(float jikiposy);
void DrawLineInView(float x1, float y1, float x2, float y2, int Color, int Thickness);
void DrawCircleInView(float x, float y, float r, int Color, int FillFlag);
void DrawAnimation(float x, float y, double ExtRate, double Angle,int TurnFlag,
int *imgarray, int allframe, float fps);
//ベクトル関数
Vector CreateVector(Vector in, float veclen);
Vector AddVector(Vector v1, Vector v2);
Vector SubVector(Vector v1, Vector v2);
Vector AddVectorInFrameTime(Vector pos, Vector speed);
Vector AddVectorInFrameTime2(Vector pos, Vector speed, Vector accel);
Vector Normalize(Vector in);
Vector RotateVector(Vector in, float radian);
float VectorLengthSquare(Vector in);
float DotProduct(Vector v1, Vector v2);
float CrossProduct(Vector v1, Vector v2);
void SetLine2DKatamuki(Line2D *in);
void DrawLine2D(Line2D in, int Color, int Thickness);
void DrawBall2D(Ball2D in, int Color, int Fill);
//当たり判定関数
bool HitTestLineAndBall(Line2D linein, Ball2D ballin);
bool IsPointAtLineFace(Line2D linein, Point2D ptin);
bool HitTestLineAndLine(Line2D line1, Line2D line2);
bool HitTestBallAndBall(Ball2D a, Ball2D b);
bool HitTestPointAndBox(Rect2D rect, Point2D pt);
//タイマー関数
void SetSimpleTimer(int idx, int time);
int GetPassedTime(int idx);


//グローバル変数
extern float g_frametime;
extern Rect2D g_framerect;//画面領域(当たり判定)
extern Point2D g_current_field_pos;//現在の左上座標
extern Rect2D g_stagesize;//ステージサイズ

//定数宣言
const float ZEROVALUE = 1e-10f;
const float PIE = 3.1415926f;
const int SCROLL_LIMIT = 200;
----------------------------------------------------------------
 エラー内容
1>myhelper.obj : error LNK2019: 未解決の外部シンボル "void __cdecl MyMain(void)" (?MyMain@@YAXXZ) が関数 _WinMain@16 で参照されました
1>C:\Documents and Settings\Owner\My Documents\Visual Studio 2008\Projects\my\Debug\my.exe : fatal error LNK1120: 外部参照 1 が未解決です
1>my - エラー 2、警告 0
ビルド: 0 正常終了、1 失敗、0 更新不要、0 スキップ
----------------------------------------------------------------
画像を貼り付けときます
(見えにくい場合→http://www.dotup.org/uploda/www.dotup.org154142.jpg.html)
初心者なのでわかりやすくお願いします

Microsoft Visual Studio 2008
Version 9.0.21022.8 RTM
Microsoft .NET Framework
Version 3.5 SP1
----------------------------------------------------------------
新しいプリジェクト→Win32 コンソール アプリケーション(ソリューションのディレクトリを作成 チェック外す)→Windows アプリケーション(空のプロジェクト チェック外す)
----------------------------------------------------------------
 プログラム

 mymain.cpp
#include "myhelper.h"
#include "mymain.h"

//自...続きを読む

Aベストアンサー

ファイル構成から推測するに
mymain.cpp というファイルに
void MyMain(void) {
// ここに処理を書く
}
という関数が必要なようです。

QC++/CLIでの画像情報(RGB)の取得

Visual C++ 2005のC++/CLI対応で、.NET Frameworkのクラスライブラリを使用し、画像処理のプログラムを作成しています。
pictureBox1->Image = gcnew Bitmap( ファイル名 );
で、画像を表示するところまではできたのですが、表示したBitmapデータのRGBカラー情報を取得する方法がわからず、困っています。
ご存知の方、教えてください。
また、このような情報が載っている書籍やサイトがありましたら、合わせて教えてください。
よろしくお願いします。
必要な情報が抜けていましたら、お手数ですが、ご指摘お願いします。

Aベストアンサー

最初に訂正ですが、 ToArgv() メソッドのことは忘れてください。
RGB情報を取得したいとは、R,G,B それぞれの値を取得したいということですよね?
Color 構造体に、R,G,B というそのまんまの読取専用のプロパティがありました。

手順は
(1) Bitmap からColorオブジェクトを取得
(2) Color 構造体のR,G,B というプロパティにアクセス。
という感じです。

class Bitmap{
public:
Color GetPixel(X, Y);
};

struct Color{
int R, G, B;
int ToArgv(); // このメソッドは無視する
}; // C++ は構造体の中にもメソッドを書ける

というクラスと構造体があって、
Bitmap::GetPixel(X, Y) でColorオブジェクトが取得できます。
Bitmap bmp = new Bitmap() ; // 仮想コード
Color color = bmp.GetPixel(X, Y);

となります。
次に、取得したColor構造体のオブジェクトcolor を利用して、それぞれのRGB値を取得します。

unsigned red = color.R;
unsigned green = color.G;
unsigned blue = color.B;

以下、bmp.bmp というビットマップの全Pixel のRGBを result.txt というファイルに書き込むサンプルです。(CLR コンソールアプリ )

// メイン プロジェクト ファイルです。

#include "stdafx.h"

#using <System.Drawing.dll>
using namespace System;
using namespace System::IO;
using namespace System::Drawing;

int main(array<System::String ^> ^args){
StreamWriter^ sr = File::CreateText ("result.txt");
Bitmap^ bmp = gcnew Bitmap("bmp.bmp");

for (int i = 0; i < bmp->Width; i++){
for (int j = 0; j < bmp->Height; j++){
Color col = bmp->GetPixel(i,j);
unsigned int red = col.R;
unsigned int grn = col.G;
unsigned int ble = col.B;

sr->WriteLine("( {0}, {1} ) - R : {2}, G : {3}, B : {4}", i,j,red,grn,ble);
}
}

sr->Close();

return 0;
}

最初に訂正ですが、 ToArgv() メソッドのことは忘れてください。
RGB情報を取得したいとは、R,G,B それぞれの値を取得したいということですよね?
Color 構造体に、R,G,B というそのまんまの読取専用のプロパティがありました。

手順は
(1) Bitmap からColorオブジェクトを取得
(2) Color 構造体のR,G,B というプロパティにアクセス。
という感じです。

class Bitmap{
public:
Color GetPixel(X, Y);
};

struct Color{
int R, G, B;
int ToArgv(); // このメソッドは無視する
}; // C++ ...続きを読む

QガウシアンフィルタのCプログラム

画像を平滑化する手法にガウシアンフィルタというものがあります。
現在、このガウシアンフィルタをCで作成しようとしていますが、いまいち分かりません。

自分なりに調べてみたところ、平滑化の移動平均フィルタやメディアンフィルタに関しては様々な書籍やサイトがあるのですが、ガウシアンフィルタに関してはあまり見つかりませんでした。

行いたい処理は、簡単に次の通りです。
画像ファイルの読み込み

フィルタ処理

処理後の画像をファイル出力

ガウシアンフィルタに関して詳しく書いてある書籍やサイトがあればお教え願います。できれば、ソースプログラムも書いてあると助かります。

当方、参考書籍として、「C言語で学ぶ実践画像処理-井上他」という本を使用しています。

Aベストアンサー

ググってみたところ
http://teo.sourceforge.jp/doc/TeoProgrammingGuide/section5-2.html
ここが最も分かりやすかったです。

f(x,y)=exp(-(x^2+y^2)/(2*sigma^2))
で、x,yはそれぞれ整数座標で計算すればよいようです。
上webページの説明だと、x,yそれぞれ-1~1の3x3座標、つまり注目座標の9近傍で打ち切っています。
その9個のf(x,y)の加算値をaとすると、ゲインが1となるようにf(x,y)/aを用います。(これを正規化と呼びます)

Q画像を読み込む配列の確保。

C言語について質問です。
画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。

メインの部分のみ記述します。

int xsize, ysize, i;
unsigned char **src;
char filename[30];
FILE *fp;

printf("ファイル名を入力してください:"); scanf("%s", filename);
printf("画像の幅:");scanf("%d", &xsize);
printf("画像の高さ:");scanf("%d", &ysize);

src = (unsigned char **)malloc(sizeof(unsigned char *) * ysize);
for(i=0; i<ysize; i++)
src[i] = (unsigned char *)malloc(sizeof(unsigned char) * xsize);
fp = fopen(filename, "rb");
fread(src[0], sizeof(unsigned char), xsize * ysize, fp);


このように記述し、エラーもなく実行できたのですが、srcをこのまま出力すると変?な画像となって出力されてしまいました。
上のように記述した場合、矛盾する場所はあるでしょうか?
そして、この方法以外に配列を確保する方法はあるでしょうか?

C言語について質問です。
画像を読み込む時、その画像の幅、高さを入力し、そのサイズに見合った配列を確保します。その後ファイル名を入力し、配列に読み込むプログラムを作成しました。

メインの部分のみ記述します。

int xsize, ysize, i;
unsigned char **src;
char filename[30];
FILE *fp;

printf("ファイル名を入力してください:"); scanf("%s", filename);
printf("画像の幅:");scanf("%d", &xsize);
printf("画像の高さ:");scanf("%d", &ysize);

src = (unsigned char **)malloc(si...続きを読む

Aベストアンサー

★最初に ysize 分のポインタを管理領域と呼んでいません。
・プログラマが malloc(1000) として 1000 バイトを確保した場合、
 実際のメモリ上には
 (1)malloc() 関数がメモリ確保の管理情報を数バイト保持(8~16バイトほど)
 (2)実際にプログラマが使用できる 1000 バイトの領域
 となります。つまり、使用できる 1000 バイトの領域の先頭に数バイトのメモリ管理情報が
 存在するのです。
・詳しい内部の仕組みは分かりませんが、確保したメモリ領域をリストデータで管理していると
 思います。リストデータはポインタで次々にデータをチェインしますよね。
 そのとき、次のデータ位置を表すポインタや確保サイズなどの数バイトが malloc() 関数などの
 メモリ管理情報(領域)として存在するわけです。
・以上を踏まえて回答 No.4 を読んでみて下さい。
 もう少し分かりやすく説明すると
 char *a = malloc(1000);
 char *b = malloc(2000);
 char *c = malloc(3000);
 char *d = malloc(4000);
 の4つのメモリは合計で 10000 バイト確保され 10000 バイトを使用できます。
 でも、実際のメモリ上には、メモリ管理情報(領域)=ヘッダが存在しますので
 a…8 + 1000
 b…8 + 2000
 c…8 + 3000
 d…8 + 4000
 で合計 10032 バイトのメモリを消費します。なお、8 バイトが管理情報ですが、昔使っていた
 コンパイラを調べたときのサイズです。今はどれくらいか分かりませんが数バイトはあります。
・メモリを節約したい場合は、回答者 No.5 さんのマクロ関数が一番節約できると思います。
 前回も同じような感じでアドバイスしたときにマクロ関数を紹介しようと思いましたが、
 それを使うのがスッキリしなくて unsigned char **src を使って src[y][x] とアクセスしたいのかと
 思いましたのでマクロ使用の紹介は控えました。が、他の回答者さんのお礼にマクロ関数のことが
 よく分からないとなっていましたね。今回はマクロ関数を利用する方がメモリを節約できます。
・マクロ関数を利用すれば、画像の横×高さのサイズ分だけ確保すればよいので src[] のポインタ分の
 メモリは節約できます。
・以上。malloc() などは『実際のメモリ使用量=メモリ管理情報(領域)+確保サイズ』です。

★最初に ysize 分のポインタを管理領域と呼んでいません。
・プログラマが malloc(1000) として 1000 バイトを確保した場合、
 実際のメモリ上には
 (1)malloc() 関数がメモリ確保の管理情報を数バイト保持(8~16バイトほど)
 (2)実際にプログラマが使用できる 1000 バイトの領域
 となります。つまり、使用できる 1000 バイトの領域の先頭に数バイトのメモリ管理情報が
 存在するのです。
・詳しい内部の仕組みは分かりませんが、確保したメモリ領域をリストデータで管理していると
 思います。リ...続きを読む

QBMPファイルの輝度を配列で表す

はじめての投稿です。よろしくお願いします。
ただいまC++でBMPファイル処理の勉強をしています。わからないところがBMPファイル(480×640)を読み込みその画像の輝度を配列(480×640)でテキストファイルに書き込みたいのですが、途中から配列がずれてしまいます。
各ピクセルからRGB値を読み込み輝度yを求めてるのですが、最初にBMPファイルのヘッダーを読み込んでしまってるんでしょうか?どなたかご教授お願いします。プラットフォームはWin32です。
以下にソースコードを載せます。

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#pragma warning( disable : 4996 )
#pragma warning( disable : 4244 )
#pragma warning( disable : 4700 )

int main(void){

BITMAPFILEHEADER BmpHead = { 0 };
int R, G, B, y;
FILE *fpi, *fpy;

/* y値出力のオープン */
if((fpy=fopen("test.txt", "a")) == NULL){
fprintf(stderr, "output file open error\n");
exit(1);
}

/*画像の読込*/
if((fpi = fopen("filename.bmp","rb")) != NULL ){
fread( &BmpHead, sizeof(BmpHead), 1, fpi );
fseek( fpi, BmpHead.bfOffBits, SEEK_SET );

int h,l;
static int matrixy[480][640];//画像のサイズ480×640
for(h=0;h<480;h++){
for(l=0;l<640;l++){

B = fgetc(fpi);
G = fgetc(fpi);
R = fgetc(fpi);

y=0.298912*R+0.586611*G+0.114478*B;/*輝度の算出*/

fprintf(fpy,"%f,",y);
}
fprintf(fpy,"\n");
}
}
fclose(fpy);
fclose(fpi);
}

よろしくお願いします。

はじめての投稿です。よろしくお願いします。
ただいまC++でBMPファイル処理の勉強をしています。わからないところがBMPファイル(480×640)を読み込みその画像の輝度を配列(480×640)でテキストファイルに書き込みたいのですが、途中から配列がずれてしまいます。
各ピクセルからRGB値を読み込み輝度yを求めてるのですが、最初にBMPファイルのヘッダーを読み込んでしまってるんでしょうか?どなたかご教授お願いします。プラットフォームはWin32です。
以下にソースコードを載せます。

#include <stdio.h>
#includ...続きを読む

Aベストアンサー

最初に書いたように、示された条件に限定すれば問題無いはずです。
となれば
・条件が間違っている
「24bitBGR無圧縮」「幅640x高さ480」「BMPファイル」のどれかが実際と違う
画像閲覧ソフトには、その画像の詳細なデータを調べられるものがります。それで条件が間違ってないか確認してみましょう。

・テキストの確認方法が間違っている
1行に (1~3桁(0~255)+カンマ1桁) x 640 = 1280~2560桁です。
使用したテキストエディタやビューアによっては、途中までしか表示できなかったり、折り返して次の行になっていたりする可能性があります。
特に、最初の内は0が多いので桁数も少ないですが、円の中心に近付けば255が多くなって桁が増えます。

確実に表示できるソフトを使う、とか、csvとしてExcel(2007以降でないと列が足りない)やOpenOfficeで開いてみるとかしてはどうでしょう。


人気Q&Aランキング