usagi / virtual-keyboard-prototype-1

仮想キーボード試作1型
3 stars 0 forks source link

OSXでfront-camのサイズが設定通りにならず巨大化する問題 #48

Closed usagi closed 10 years ago

usagi commented 10 years ago

from: https://github.com/usagi/virtual-keyboard-prototype-1/issues/46#issuecomment-32883499

front-camのウインドウが大きかったです。

usagi commented 10 years ago

記憶によると、

usagi commented 10 years ago

カメラ部分のミニマル検証用コードです。

#include <iostream>
#include <stdexcept>

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

namespace arisin
{
  namespace etupirka
  {
    struct configuration_t
    {
      std::string video_file_top;
      std::string video_file_front;
      struct camera_capture_configuration_t
      {
        int top_camera_id;
        int front_camera_id;
        int width;
        int height;
      } camera_capture;
    };

    class camera_capture_t final
    {
    public:
      struct captured_frames_t
      {
        cv::Mat top;
        cv::Mat front;
      };

    private:
      static constexpr size_t top   = 0;
      static constexpr size_t front = 1;

      std::array<cv::VideoCapture, 2> captures;

      int top_camera_id_;
      int front_camera_id_;
      int width_;
      int height_;
      std::string video_file_top_;
      std::string video_file_front_;

    public:
      camera_capture_t(const configuration_t& conf);
      captured_frames_t operator()();
      const int top_camera_id() const;
      const int front_camera_id() const;
      const int width() const;
      const int height() const;
    };
  }
}

namespace arisin
{
  namespace etupirka
  {
    camera_capture_t::camera_capture_t(const configuration_t& conf)
      : top_camera_id_(conf.camera_capture.top_camera_id)
      , front_camera_id_(conf.camera_capture.front_camera_id)
      , width_(conf.camera_capture.width)
      , height_(conf.camera_capture.height)
      , video_file_top_(conf.video_file_top)
      , video_file_front_(conf.video_file_front)
    {
      std::cerr << "top-cam-id: "       << top_camera_id_ << "\n";
      std::cerr << "front-cam-id: "     << front_camera_id_ << "\n";
      std::cerr << "width: "            << width_ << "\n";
      std::cerr << "height: "           << height_ << "\n";
      std::cerr << "video-file-top: "   << video_file_top_ << "\n";
      std::cerr << "video-file-front: " << video_file_front_ << "\n";

      if(conf.video_file_top.empty())
      {
        captures[top].set(CV_CAP_PROP_FRAME_HEIGHT, height_);
        captures[top].set(CV_CAP_PROP_FRAME_WIDTH , width_);
        std::cerr << "top-cam set height and width" << "\n";
      }

      if(conf.video_file_front.empty())
      {
        captures[front].set(CV_CAP_PROP_FRAME_HEIGHT, height_);
        captures[front].set(CV_CAP_PROP_FRAME_WIDTH , width_);
        std::cerr << "front-cam set height and width" << "\n";
      }

      if(conf.video_file_top.empty())
        captures[top].open(top_camera_id_);
      else
        captures[top].open(conf.video_file_top);

      if(!captures[top].isOpened())
        throw std::runtime_error("top-cam can not opened");
      std::cerr << "top-cam opened" << "\n";

      if(conf.video_file_front.empty())
        captures[front].open(front_camera_id_);
      else
        captures[front].open(conf.video_file_front);

      if(!captures[front].isOpened())
        throw std::runtime_error("front-cam can not opened");
      std::cerr << "front-cam opened" << "\n";
    }

    camera_capture_t::captured_frames_t camera_capture_t::operator()()
    {
      camera_capture_t::captured_frames_t r;

      cv::Mat tmp;

      captures[top] >> tmp;
      r.top = tmp.clone();
      std::cerr << "top-cam captured" << "\n";

      captures[front] >> tmp;
      r.front = tmp.clone();
      std::cerr << "front-cam captured" << "\n";

      if(!video_file_top_.empty() && captures[top].get(CV_CAP_PROP_POS_FRAMES) == captures[top].get(CV_CAP_PROP_FRAME_COUNT))
      {
        std::cerr << "top-cam to reload video file: " << video_file_top_ << "\n";
        captures[top].release();
        captures[top].open(video_file_top_);
        if(!captures[top].isOpened())
          throw std::runtime_error("top-cam can not opened");
      }

      if(!video_file_front_.empty() && captures[front].get(CV_CAP_PROP_POS_FRAMES) == captures[front].get(CV_CAP_PROP_FRAME_COUNT))
      {
        std::cerr << "front-cam to reload video file: " << video_file_front_ << "\n";
        captures[front].release();
        captures[front].open(video_file_front_);
        if(!captures[front].isOpened())
          throw std::runtime_error("front-cam can not opened");
      }

      return std::move(r);
    }

    const int camera_capture_t::top_camera_id() const
    { return top_camera_id_; }

    const int camera_capture_t::front_camera_id() const
    { return front_camera_id_; }

    const int camera_capture_t::width() const
    { return width_; }

    const int camera_capture_t::height() const
    { return height_; }

  }
}

#include <memory>
#include <thread>

int main()
{
  using namespace arisin::etupirka;

  configuration_t c;
  c.camera_capture.top_camera_id = 0;
  c.camera_capture.front_camera_id = 1;
  c.camera_capture.width = 640;
  c.camera_capture.height = 480;

  std::unique_ptr<camera_capture_t> p;
  p.reset(new camera_capture_t(c));

  bool is_continue = true;

  std::thread t([&](){
    std::string a;
    std::getline(std::cin, a);
    is_continue = false;
  });

  while(is_continue)
  {
    const auto frames = (*p)();
    std::cerr << "top-image-size  : " << frames.top.cols   << ", " << frames.top.rows   << "\n";
    std::cerr << "front-image-size: " << frames.front.cols << ", " << frames.front.rows << "\n";
    cv::waitKey(33);
  }

  t.join();
}

このソースを適当な場所にa.cxxなど保存してclang++ a.cxx -lopencv_highgui -lopencv_coreなどしてビルドし、実行してみて下さい。

実行すると、内部的にはカメラからきちんとキャプチャーしますが、GUIは省略して、top/frontそれぞれから取得した画像の大きさをコンソールに出力します。終了はENTERです。

@arisin こちらもお手数ですがお時間とれるときにテストおねがいします。

arisin commented 10 years ago

opencv2のファイルが無いとのエラーが出てしましました。 よろしくお願いします。

  << clang++ a.cxx -lopencv_highgui -lopencv_core                                                 [master]
a.cxx:4:10: fatal error: 'opencv2/core/core.hpp' file not found
#include <opencv2/core/core.hpp>
         ^
1 error generated.
usagi commented 10 years ago

find / -type d -iname opencv2とかしてヘッダーあるか、ディレクトリーの構成は<opencv2/ccore/core.hpp>でいいか確認するじゃん。

したら、clang++-I/dokoka/sokoka/kokokayo/includeって<opencv2/core/core.hpp>がある場所を渡すじゃん。

arisin commented 10 years ago

すみません。ありがとうございます。

arisin commented 10 years ago

opencv2がある場所を調べ、

  << find / -type d -iname opencv2 2>/dev/null                                                    [master]
/opt/local/include/opencv2

clang++に-I オプションで渡してみましたが、エラーが。調査します。

  << clang++ a.cxx -lopencv_highgui -lopencv_core -I /opt/local/include/                         [master]
a.cxx:4:10: fatal error: 'opencv2/core/core.hpp' file not found
#include <opencv2/core/core.hpp>
         ^
1 error generated.
usagi commented 10 years ago

わたしの-Iオプションの付け方よくみれ。

usagi commented 10 years ago

image

man gcc より -Iオプションの項目。 -Idir であって -I dir ではない。

arisin commented 10 years ago

スペースを入れてしましました。

  << clang++ a.cxx -lopencv_highgui -lopencv_core -I/opt/local/include/                          [master]
a.cxx:4:10: fatal error: 'opencv2/core/core.hpp' file not found
#include <opencv2/core/core.hpp>
         ^
1 error generated.

スペースを取り除いてもまだエラーになるので、調べます。

usagi commented 10 years ago

めんどくさいから#include "/dokoka/sokoka/kokoka/opencv2/core/core.hpp"に書き換えてしまえ。

usagi commented 10 years ago

OpenCVのヘッダーファイル内部での#includeの記述の癖により↑はダメでしたごめんなさいごめんんさいごめんなさい。

arisin commented 10 years ago
sudo ln -s /opt/local/include/opencv2 /usr/local/include/opencv2

で、シンボリックリンクを作成。 しかし、エラー内容が。調査します。

  << clang++ a.cxx -lopencv_highgui -lopencv_core                                                 [master]
a.cxx:37:39: error: implicit instantiation of undefined template 'std::__1::array<cv::VideoCapture, 2>'
      std::array<cv::VideoCapture, 2> captures;
                                      ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/__tuple:68:60: note: 
      template is declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TYPE_VIS array;
                                                           ^
1 error generated.
usagi commented 10 years ago

いちおう言っておくと、Mint16ではそもそもテスト用のコードはもちろんg++-4.8、clang++-3.4でビルド、実行確認してます。

usagi commented 10 years ago

どうやらfrontが巨大化するのではなく、UCAM-DLE300Tが巨大化(限界性能解像度)になるようです。 id=1,2で確認したところ、両方巨大化してたので。

usagi commented 10 years ago

問題はどうやら「OSXにUCAM-DLE300Tを使う場合に、cv::VideoCapture::setにCV_CAP_PROP_FRAME_HEIGHTとCV_CAP_PROP_FRAME_WIDTHが何故か効果が無い」よなるようだ。

usagi commented 10 years ago

可能性の検証: 「OSXではopenした後にsetしないとダメ説」

結果: Yes