/* * Copyright (c) 2017 TOYOTA MOTOR CORPORATION * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "camera.h" #include <QPainter> #include <opencv2/imgproc.hpp> #include <linux/videodev2.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> using namespace cv; Camera::Camera() { running = false; timer = new QTimer(this); capture = new VideoCapture(); connect(timer, SIGNAL(timeout()), this, SLOT(grab())); } Camera::~Camera() { if (timer->isActive()) timer->stop(); if (capture && capture->isOpened()) capture->release(); delete timer; delete capture; } void Camera::paint(QPainter *painter) { painter->drawImage(0, 0, image); } void Camera::enumerateCameras() { int maxID = 10; for (int idx = 0; idx <maxID; idx++){ std::stringstream no; no << "/dev/video" << idx; qDebug() << idx; int fd = open(no.str().c_str(), O_RDWR); if (fd != -1){ struct v4l2_capability cap; if (ioctl(fd,VIDIOC_QUERYCAP,&cap) != -1){ if ((cap.capabilities & (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)) == (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING)){ qDebug()<< (char*)(cap.driver) << ">" << (char*)(cap.card) << ">" << (char*)(cap.bus_info);// << (cap.version>>16)&0xFF << (cap.version>>8)&0XFF << cap.version&0xFF; cam_arr.push_back(idx); // vector of all available cameras } } close(fd); } } camcnt = cam_arr.length(); cam_arr_bak = cam_arr; } void Camera::start(int no, int fps, QString res) { try{ for (QVariantList::iterator iter = cam_arr_bak.begin(); iter != cam_arr_bak.end(); ++iter){ if (*iter == no){ cam_arr_bak.erase(iter); break; } } if (capture && capture->open(no)){ capture->set(CAP_PROP_FRAME_WIDTH, res.section("*", 0, 0).toInt()); capture->set(CAP_PROP_FRAME_HEIGHT, res.section("*", 1, 1).toInt()); if (fps > 0){ timer->start(1000/fps); running = true; emit isrunningChanged(running); emit camraCntChanged(cam_arr_bak); } camnumbackup = no; } } catch(cv::Exception & e) { qDebug() << "als-meter-demo open device error: " << e.msg.c_str(); } } void Camera::stop() { cam_arr_bak.push_back(camnumbackup); if (timer->isActive()) timer->stop(); if (capture && capture->isOpened()) capture->release(); image = QImage(); update(); running = false; emit isrunningChanged(running); emit camraCntChanged(cam_arr_bak); } QVariantList Camera::camranum() const{ return cam_arr_bak; } int Camera::cameraCnt() { return camcnt; } bool Camera::isrunning() const{ return running; } void Camera::grab() { if (capture && capture->isOpened()){ Mat frame; capture->read(frame); if (!frame.empty()){ image = QImage((const uchar*)(frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888).rgbSwapped(); image = image.scaled(this->width(), this->height(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); update(); } } }