目次
today: ?
yesterday: ?
total: ?
更新履歴
2011/07/09
- プログラム公開
推奨環境
- OS: Linux(Ubuntu 11.04で確認)
- OpenCV: 2.3(無くても使える)
- webcam: svn版(インストール方法はここでは書きません)
このプログラムでできること
- Qcam Orbit AFのパン・チルト
- UVC対応カメラのパラメータの変更
ファイル構成
- main.cpp: 要OpenCV
- webcam.hpp: これだけなら少し書き換えればOpenCVなしでも可
- param.yml: 再コンパイルしないでもいくつかのパラメータはここで変更可能
ダウンロード用ファイル
main関数の流れ
/**
* @file main.cpp
* @author Kato Ryuichi <kato@hyrrokkin>
* @date Fri Jul 8 11:29:19 2011
*
* @brief Qcam Orbit AFUVC Camera (046d:0994)対応
* パン・チルト制御プログラム
*
*/
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
void capMiss(int capNum, string testImg);
void imgSave(string filePath, vector<Mat> &takeCap);
void help(void){
cout << "./webcam [-i lena.jpg] [-v video0]" << endl;
}
int main(int argc, char **argv){
string testImg = "lena.jpg";
int capNum = -1;
string videoNum = "video0";
for(int i = 0; i < argc; i++){
if(strcmp(argv[i],"-v") == 0){
videoNum = argv[++i];
capNum = (int)videoNum[5] - 48;
cout << "Use /dev/video" << capNum << endl;
}else if(strcmp(argv[i],"-i") == 0)
testImg = argv[++i];
else
help();
}
FileStorage cvfs("param.yml", FileStorage::READ);
int fc, sh, w, h;
string list;
if(cvfs.isOpened()){/// read param.yml
cvfs["list"] >> list;
cvfs["focus"] >> fc;
cvfs["sharpness"] >> sh;
cvfs["width"] >> w;
cvfs["height"] >> h;
}else{
cout << "[ERROR] YML file not found!" << endl;
return -1;
}
namedWindow("image", CV_WINDOW_AUTOSIZE);
namedWindow("cap", CV_WINDOW_AUTOSIZE);
VideoCapture cap(capNum);
if(!cap.isOpened())
capMiss(capNum, testImg);
cap.set(CV_CAP_PROP_FRAME_WIDTH, w);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, h);
Webcam wc(videoNum);
wc.devInfo();/// Show device information
if(list == "ON" || list == "On" || list == "on")
wc.devCtrlLists();/// Show device control lists
wc.sharpness(sh, false);
wc.focus(fc, false);
int key, i = 0;
int volume = 800;
vector<Mat> save;
while(1){
stringstream now;
now << i;
string fullname;
if(i < 10)
fullname = "capture-0" + now.str() + ".png";
else
fullname = "capture-" + now.str() + ".png";
Mat frame;
cap >> frame;
imshow("cap", frame);
key = waitKey(10);
if(key == 'c'){/// image capture
imwrite(fullname, frame);
i++;
}
if(key == 'a')
wc.panTilt("pan", -volume);
if(key == 's')
wc.panTilt("PAN", volume);
if(key == 'w')
wc.panTilt("tilt", -volume);
if(key == 'z')
wc.panTilt("Tilt", volume);
if(key == 'q')
break;
}
return 0;
}
void capMiss(int capNum, string testImg){
cout << "Could not find a USB camera!" << endl
<< "? Device path /dev/video" << capNum << " ?" << endl;
Mat img = imread(testImg, CV_LOAD_IMAGE_COLOR);
imshow("image", img);
waitKey(0);
exit(0);
}
webcam.hppの流れ
/* $Id: webcam.hpp 2011/07/08 11:49:47 kato Exp $
* エラー処理と時間計測のためにOpenCV使ってますが,
* そこだけ書き換えればOpenCVなしでも動きます.
*
* Test program for libwebcam.
* Copyright (c) 2006-2007 Logitech.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef
#define
#include
#include
#include
#include
using namespace std;
using namespace cv;
class Webcam{
private:
CResult cRet;
string devName;
CHandle handle;
public:
Webcam();
~Webcam();
Webcam(string usbName);
void initialize(string usbName);
void devInfo();
void devCtrlLists();
void ctrlInfo(CControl *cCtrl);
int focus(int val, bool check);
int sharpness(int val, bool check);
//int panTiltReset(int val);
int panTilt(string pt, int val);
};
Webcam::Webcam(){}
Webcam::Webcam(string usbName)
:handle(0)
{
initialize(usbName);
}
Webcam::~Webcam(){
cout << devName << " release" << endl;
c_cleanup();
}
/**
* webcam.hの初期化
*
* @param usbName 使用するカメラ名(ex. "video0")
*/
void Webcam::initialize(string usbName){
CResult cRet = c_init();
if(cRet)
cout << "Unable to c_init (" << cRet << ")" << endl;
devName = usbName;
}
/**
* 初期化したカメラの情報を表示する.
*
*/
void Webcam::devInfo(){
try{
CV_Assert(!handle && !devName.empty());
}catch(Exception e){
exit(0);
}
unsigned int size = sizeof(CDevice)
+ (devName.c_str() ? strlen(devName.c_str()) : 32) + 84;
CDevice *info = (CDevice *)malloc(size);
assert(info);
handle = c_open_device(devName.c_str());
int ret = c_get_device_info(handle, devName.c_str(), info, &size);
if(ret)
cout << "Failed to c_get_device_info " << ret << endl;
else
cout << "-[c_get_device_info(hanlde: " << handle << ")]- -" << endl
<< " ShortName = " << info->shortName << "," << endl
<< " Name = " << info->name << "," << endl
<< " Driver = " << info->driver << "," << endl
<< " Location = " << info->location << "," << endl
<< " (vid, pid, bcd) = ("
<< info->usb.vendor << ", "
<< info->usb.product << ", "
<< info->usb.release << ")" << endl
<< "- - - - - - - - - - - - - - - - - -" << endl;
free(info);
}
/**
* 初期化したカメラでコントロールできるパラメータの情報を表示する.
*
*/
inline void Webcam::devCtrlLists(){
unsigned int size = 0, count = 0;
cout << "Getting control information for handle " << handle << endl;
CResult ret = c_enum_controls(handle, NULL, &size, &count);
if(ret == C_BUFFER_TOO_SMALL){
CControl *cCtrls = (CControl *)malloc(size);
ret = c_enum_controls(handle, cCtrls, &size, &count);
if(ret)
cout << "Unable to c_enum_controls (" << ret << ")" << endl;
for(int i = 0; i < (int)count; i++) {
CControl *cCtrl = &cCtrls[i];
ctrlInfo(cCtrl);
}
free(cCtrls);
}else
cout << "No controls found (ret = " << ret << ")" << endl;
}
/**
* パラメータを呼び出す
*
* @param cCtrl パラメータリスト
*/
inline void Webcam::ctrlInfo(CControl *cCtrl){
cout << cCtrl->name << " (id:" << cCtrl->id << ")" << endl
<< " [type: " << cCtrl->type << ","
<< " flags: " << cCtrl->flags << ",";
if(cCtrl->type == CC_TYPE_CHOICE){
cout << " choice = {";
for(int i = 0; i < (int)cCtrl->choices.count; i++){
cout << " '" << cCtrl->choices.list[i].name << "'"
<< "[" << cCtrl->choices.list[i].index << "]";
}
cout << " }";
}else{
cout << " min: " << cCtrl->min.value
<< ", max: " << cCtrl->max.value
<< ", def: " << cCtrl->def.value
<< ", step: " << cCtrl->step.value;
}
cout << "]" << endl;
}
/**
* 焦点距離を変更する
*
* @param val 変更する値(devCtrlLists()で表示範囲内で)
* @param check いくつに変更したか表示する(デバック用?)
*
* @return 正しく変更できたら0を返す
*/
inline int Webcam::focus(int val, bool check){
try{
CV_Assert(0 <= val && val <= 255);
}catch(Exception e){
cout << " val: " << val << " (0 < val < 255)" << endl;
return -1;
}
CControlValue value;
value.value = val;
CResult ret = c_set_control(handle, (CControlId)0x2048D04, &value);
if(ret){
cout << "int Webcam::focus(int val, bool check)" << endl
<< " (handle: " << handle << ", ret: " << ret
<< ", val: " << val << ")" << endl;
return 0;
}else if(check)
cout << "handle" << handle << " Focus: " << val << endl;
return -1;
}
/**
* シャープネスの値を変更する
*
* @param val 変更する値(devCtrlLists()で表示範囲内で)
* @param check いくつに変更したか表示する(デバック用?)
*
* @return 正しく変更できたら0を返す
*/
inline int Webcam::sharpness(int val, bool check){
try{
CV_Assert(0 <= val && val <= 255);
}catch(Exception e){
cout << " val: " << val << " (0 < val < 255)" << endl;
return -1;
}
CControlValue value;
value.value = val;
CResult ret = c_set_control(handle, CC_SHARPNESS, &value);
if(ret){
cout << "int Webcam::sharpness(int val, bool check)" << endl
<< " (handle: " << handle << ", ret: " << ret
<< ", val: " << val << ")" << endl;
return 0;
}else if(check)
cout << "handle" << handle << " Sharpness: " << val << endl;
return -1;
}
/*/
inline int Webcam::panTiltReset(int val){
if(val < 0 || 3 < val){
cout << "int Webcam::sharpness(int val, bool check)" << endl
<< " val: " << val << " (0 < val < 3)" << endl;
return -1;
}
CControlValue value;
value.value = val;
CResult ret = c_set_control(handle, CC_LOGITECH_PANTILT_RESET, &value);
if(ret)
cout << "int Webcam::panTiltReset(int val)" << endl
<< " (handle: " << handle << ", ret: " << ret << ")" << endl;
else
cout << "handle" << handle << " PanTilt Reset: " << val << endl;
return 0;
}
//*/
/**
* パン・チルトを制御する
*
* @param pt パン・チルトの選択("Pan" or "Tilt")
* @param val 移動する値
*
* @return 正しく変更できたら0を返す
*/
inline int Webcam::panTilt(string pt, int val){
try{
CV_Assert(-1000 <= val && val <= 1000);
}catch(Exception e){
cout << " val: " << val << " (-1000 < val < 1000)" << endl;
return -1;
}
CControlValue value;
int num = 4;
value.value = val / num;
CResult ret = {0};
for(int i = 0; i < num; i++){
if(pt == "Pan" || pt == "pan" || pt == "PAN")
ret = c_set_control(handle, CC_PAN_RELATIVE, &value);
if(pt == "Tilt" || pt == "tilt" || pt == "TILT")
ret = c_set_control(handle, CC_TILT_RELATIVE, &value);
waitKey(25);
if(ret && !i)
cout << "void Webcam::panTilt(CHandle handle, int val)" << endl
<< " (handle: " << handle
<< ", ret: " << ret << ")" << endl;
}
return 0;
}
#endif