肌色領域の表示 open cv

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
fax

肌色領域の表示 open cv

#1

投稿記事 by fax » 14年前

コード:

#include <stdio.h>
#include <highgui.h>
#include <cv.h>

const int COLOR_TOP = 17;
const int COLOR_BOTTOM = 15;

int main(int argc, char** argv) {
  bool isStop = false;
  CvCapture *capture = NULL;
  //capture = cvCreateCameraCapture(0);
  capture = cvCaptureFromAVI("test.avi");
  if(capture == NULL){
    printf("capture device not found!!");
    return -1;
  }

  IplImage *img = NULL;
  img = cvQueryFrame(capture);
  const int w = img->width;
  const int h = img->height;

  IplImage *imgBg = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgGray = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgDiff = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgHsv = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3);
  IplImage *imgHue = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgSat = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgVal = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgThreshold1 = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgThreshold2 = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgThreshold3 = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
  IplImage *imgSkin = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);

  char winNameCapture[] = "Capture";
  char winNameDiff[] = "Difference";
  char winNameBg[] = "Background";
  char winNameSkin[] = "Skin";

  cvNamedWindow(winNameCapture, CV_WINDOW_AUTOSIZE);
  cvNamedWindow(winNameDiff, CV_WINDOW_AUTOSIZE);
  cvNamedWindow(winNameBg, CV_WINDOW_AUTOSIZE);
  cvNamedWindow(winNameSkin, CV_WINDOW_AUTOSIZE);

  img = cvQueryFrame(capture);
  cvCvtColor(img, imgBg, CV_BGR2GRAY);  

  int waitKey;
  while (1) {
    if(!isStop){
      if((img = cvQueryFrame(capture)) == NULL) break;
      cvCvtColor(img, imgGray, CV_BGR2GRAY);
      cvAbsDiff(imgGray, imgBg, imgDiff);

      cvCvtColor(img, imgHsv, CV_BGR2HSV);
      cvSplit(imgHsv, imgHue, imgSat, imgVal, NULL);
      cvThreshold(imgHue, imgThreshold1, COLOR_BOTTOM, 255, CV_THRESH_BINARY);
      cvThreshold(imgHue, imgThreshold2, COLOR_TOP, 255, CV_THRESH_BINARY_INV);
      cvAnd(imgThreshold1, imgThreshold2, imgThreshold3, NULL);

      cvAnd(imgDiff, imgThreshold3, imgSkin, NULL);

      cvShowImage(winNameCapture, img);
      cvShowImage(winNameDiff, imgDiff);
      cvShowImage(winNameBg, imgBg);
      cvShowImage(winNameSkin, imgSkin);
    }

    waitKey = cvWaitKey(33);
    if(waitKey == 'q') break;
    if(waitKey == 'b'){ // 背景再取得
      img = cvQueryFrame(capture);
      cvCvtColor(img, imgBg, CV_BGR2GRAY);
    }
    if(waitKey == ' '){
      isStop = !isStop;
      if(isStop) printf("stop\n");
      else printf("start\n");
    }
  }
  
  cvReleaseCapture(&capture);
  cvDestroyWindow(winNameCapture);
  cvDestroyWindow(winNameDiff);
  cvDestroyWindow(winNameBg);
  cvDestroyWindow(winNameSkin);
  return 0;
}
http://d.hatena.ne.jp/shokai/20090202/1233563393
上記のサイトのプログラムなんですが
skinwindowの出力画面で取り出した肌色領域を、capture画面のような、手、顔といった肌色にもどしたい場合はどうすればいいのでしょうか?
初心者なのでくわしくおしえていただけるとありがたいです

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: 肌色領域の表示 open cv

#2

投稿記事 by h2so5 » 14年前

元の画像と、肌色領域のグレースケール画像の画素値の積を取れば肌色の部分だけが表示されると思います。

但しサンブル画像では肌色領域が白ではなくグレーになっていて、そのままだと少し暗くなってしまうので、
グレースケール画像の方はコントラスト上げるとか二値化するなどの調整が必要だと思います。
オフトピック
「初心者なので」と言われてもあなたのレベルを判断する材料が何も無いため、
どのように詳しく教えるべきなのかが分かりません。C言語の基礎からいちいち説明しないといけないのでしょうか?

閉鎖

“C言語何でも質問掲示板” へ戻る