2016年1月5日火曜日

CSVファイルからデータの読込

メモ。
csvファイル( , カンマ区切り、改行あり)からデータを読み込む。
ついでにopencvのMatにデータをぶち込む。


"filename1.csv", "filename2.csv", .... , みたいな感じの連続番号を振ったCSVファイルをループ文で読み込む

while(1){
 read_csv(i);
 ++i;
}
みたいな感じ。







int read_csv(int counter) //ループのカウンター値を受け取る→連続したファイルを読み込む
{

 //ファイル名の指定
 char name[256];
 sprintf_s(name, 256, "ファイル名%d.csv", counter); //連続番号付けしたファイルを読み込む

 std::ifstream read_data(name);


 //エラー処理
 if (!read_data) {
  std::cout << "Error:Input data file not found" << std::endl;
  return -1;
 }

 double *data = new double[height*width](); //0で初期化
 //heightとwidthは定数、ここでは定義は省略している

 int i = 0;
 
 std::string str;
 while (getline(read_data, str)){
  
  string token;
  stringstream ss;
  istringstream stream(str);

  while (getline(stream, token, ',')) { // 区切り文字は ,カンマ

   // 文字列から数値に変換
   ss << token;
   ss >> data[i];
   
   ++i;

   ss.clear(); // 状態をクリア.
   ss.str(""); // 文字列をクリア.
  }
 }


 cv::Mat mat_data(height, width, CV_64FC1, data); //csvから読み込んだデータをcv::Matにぶち込む

 
 return 0;
}




インクルードするのはたしかこれら
#include <fstream>
#include <iostream>
#include <string>
#include <opencv2/opencv.hpp>

参考:
http://fa11enprince.hatenablog.com/entry/2014/04/03/233500
http://99blues.dyndns.org/blog/2010/02/std_stringstream/
http://ppp-lab.sakura.ne.jp/cpp/library/032.html
http://handasse.blogspot.com/2007/06/c_22.html




2016年1月3日日曜日

【グロ注意】キモ気持ちいい角栓動画

角栓除去の動画。

キモイけど癖になる動画。











ドイツ・ゾーリンゲン AXiON ステンレス製角栓プッシャー(オーバルループ) 高級スモーク仕上げ #slg007968fba

AOZEE 角栓・黒ニキビ専用スティックセット抗菌ステンレス黒ニキビ取り毛穴すっきり毛穴ケア





OpenCVを使ったCSVファイルの入出力。

メモ。

OpenCVのMatの値をCSVで保存する。


  char name[256]; //ファイル名

   sprintf_s(name, 256, "ディレクトリ名\\ファイル名%d.csv", counter);
   //処理全体をループ内に入れてcounterを回せば、ファイル名に連番が付く

   //フォルダがない場合は作成(direct.hをインクルードしておく )
   if (_mkdir("ディレクトリ名") == 0);

   //#include <direct.h>を忘れない
   ofstream save(name);

   double output;
   for (int y = 0; y < height; ++y){ //row:列
    for (int x = 0; x < width; ++x){
     output = data.at<double>(y, x); //画像というか単純に行列のデータ
     save << dec << output << ",";

    }
    //改行
    save << endl;
   }

   //解放
   save.close();



cv::Mat data はCV_64FC1とかを想定したもの。


で、for文で1ピクセルずつ回しているけど、書くのが面倒だったら↓みたいにOpenCVの関数使えば1行で書ける。



 //csv変換して出力
 save << cv::format(data, "csv");



以上。


2016年1月1日金曜日

OpenCVのcv::Matについてメモ(画素の扱いとか)

OpenCVのcv::Matについてメモ

勉強し始めた時、あれMatのチャンネルって何?
あれ?どうやって各画素値いじるの?
あれ全部真っ白なっちゃった!?orzってなったのでそのメモ


#include <iostream>
#include <opencv2\opencv.hpp>


#define height 100
#define width 100

 void main(){

  double* data = new double[height*width](); //0で初期化
  //省略したけど、dataになにかいろんな数値入れておく
  /*
  .... dataに数値入れる処理
  for :
  data[i] = a とかで数値入れる
  */

  //dataをMatにぶち込む
  //32F、64Fにすれば255以上の数値も扱える
  Mat input(height, width, CV_64FC1, data);


  Mat img(input.rows, input.cols, CV_8UC3); //inputと同じ行数と列数を用意


  //ここでMatの各要素にアクセスする
  for (int y = 0; y < input.rows; ++y) {
   for (int x = 0; x < input.cols; ++x) {

    //ピクセルにアクセスするためのインデックス
    //G,B,Rの順 チャンネル数は3つ必要→Matは1次元だから3倍する
    int index = ((y * input.cols) + x) * 3;

    //とりあえず画素に何か数値入れる
    //doubleの数値を扱えるのは .atだけらしい
    int rgb = input.at<double>(y, x) + (x * y) % 255; //255諧調に

    //.dataでは扱える数値の最大が255
    //B,G,Rと連続しているのでindex, index+1, index+2でアクセス可能
    img.data[index] = rgb;
    img.data[index + 1] = rgb;
    img.data[index + 2] = rgb;
    //これで1ピクセルの色を扱える

   }
  }


  delete[] data; //明示的に解放

 }

こんな感じでやる。

#define height 100
#define width 100
は定数。const int とかでもいいと思うけどとりあえず、ここではあまり重要じゃない。

double* data = new double[height*width]();
cv::Mat input(height, width, CV_64FC1, data);
height*widthの1次元配列を確保。()をつけると0で初期化できるらしい。
heigh*widthつまり100x100の行列。
CV_64FC1はdouble型の1チャンネルの行列。
CV_8UC1とか
CV_8UC3とかいろいろある。C1とかC2がチャンネル数。
RGBの画像を扱いたかったら、CV_8UC3ってやる。R、G、Bそれぞれ1チャンネルずつ使うから。
でも、想像するのは1次元配列なのでデータのアクセスではじめはややこしいと思った。

3x3の画像    数値をいじるときの想像
■■□  →  ■■□■□■□■■
■□■     [0][1] .....                [8]  
□■■   

3x3のRGB画像だったら
BGR BGR BGR   →   BGR BGR BGR BGR BGR BGR BGR BGR BGR
BGR BGR BGR        [0][1][2]     .......                       [24][25][26]
BGR BGR BGR 


input.at<double>(y, x)
255以上の数値を扱うときは.atを使う。
あとCV_32FとかCV_64FとかでMatを作る

img.data[index]         //B
img.data[index + 1]    //G
img.data[index + 2]    //R
B,G,Rと1ピクセルを1次元配列の要素3つで扱うので
3チャンネルでMatを作っておく。
.dataでアクセスして、+1, +2で3つ分。



以上。