Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When use cv::VideoCapture I get green and purple image #81

Open
fukamike opened this issue Dec 4, 2019 · 11 comments
Open

When use cv::VideoCapture I get green and purple image #81

fukamike opened this issue Dec 4, 2019 · 11 comments

Comments

@fukamike
Copy link

fukamike commented Dec 4, 2019

When I use cv::VideoCapture I get green and purple image.
I want to get right image and left image using cv::VideoCapture.

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

Screenshot from 2019-12-04 15-23-06

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

I'm using this code and compile.
`#include
#include "opencv2/opencv.hpp"

int main(int argh, char* argv[])
{
const std::string WIN_NAME = "Capture";
const int CAP_WIDTH = 752;
const int CAP_HEIGHT = 480;
// const std::string SAVE_FILE = "Img.jpg";

//デバイスのオープン
cv::VideoCapture cap(0);
//cap.open(0);

//オープン失敗?
if(!cap.isOpened())
{
    std::cout << "ERROR: cannot open cam device." << std::endl;
    return -1;
}

//キャプチャサイズの設定
cap.set(CV_CAP_PROP_FRAME_WIDTH, CAP_WIDTH);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, CAP_HEIGHT);

//ループ
while(1)
{
    cv::Mat frame;
    // 1フレームキャプチャ
    //cap >> frame;
    if (!cap.read(frame))
    {
        std::cout << "ERROR: cannot capture." << std::endl;
        break;
    }

    //表示
    cv::imshow(WIN_NAME, frame);

    //キー待ち
    int inp_key = cv::waitKey(1);

    //入力あり?
    if (inp_key >= 0) {
        // [ESC] or 'Q' or 'q'
        if (inp_key == 27 || inp_key == 81 || inp_key == 113) break;

        // 'S' or 's'
        //else if(inp_key == 83 || inp_key == 115)
        //{
        //  //フレーム画像を保存する
        //  cv::imwrite(SAVE_FILE, frame);
        //}
    }
} //end of while

//ウィンドウ破棄
cv::destroyAllWindows();

return 0;

}`

g++ camera.cpp -I/usr/local/include/opencv2 -I/usr/local/include/opencv -L/usr/local/lib -lopencv_core -lopencv_imgcodecs -lopencv_highgui -lopencv_video -lopencv_videoio

@harjeb
Copy link
Contributor

harjeb commented Dec 4, 2019

You need spilt raw data like:

    // Split raw data to two images
    const int &w = raw.cols, &h = raw.rows;
    const int size = w * h;
    if (left.cols != w || left.rows != h || left.type() != CV_8UC1)
        left = cv::Mat(h, w, CV_8UC1);
    if (right.cols != w || right.rows != h || right.type() != CV_8UC1)
        right = cv::Mat(h, w, CV_8UC1);
    unsigned char *data = raw.data;
    for (int i = 0; i < size; ++i) {
        left.data[i] = data[i*2];       // Y1   Y2
        right.data[i] = data[i*2 + 1];  //    U    V
    }
    cv::imshow("left", left);
    cv::imshow("right", right);

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

I succeed compile and run program.
I indicate the result.
Screenshot from 2019-12-04 16-35-51
`#include
#include "opencv2/opencv.hpp"

int main(int argh, char* argv[])
{
const std::string WIN_NAME = "Capture";
const int CAP_WIDTH = 752;
const int CAP_HEIGHT = 480;
// const std::string SAVE_FILE = "Img.jpg";

//デバイスのオープン
cv::VideoCapture cap(0);
//cap.open(0);

//オープン失敗?
if(!cap.isOpened())
{
    std::cout << "ERROR: cannot open cam device." << std::endl;
    return -1;
}

//キャプチャサイズの設定
cap.set(CV_CAP_PROP_FRAME_WIDTH, CAP_WIDTH);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, CAP_HEIGHT);

//ループ
while(1)
{
    
    cv::Mat frame;
cap >> frame;
cv::Mat left;
cv::Mat right;
const int &w = frame.cols, &h = frame.rows;
	const int size = w * h;
	if (left.cols != w || left.rows != h || left.type() != CV_8UC1)
   		 left = cv::Mat(h, w, CV_8UC1);
if (right.cols != w || right.rows != h || right.type() != CV_8UC1)
   		 right = cv::Mat(h, w, CV_8UC1);
	unsigned char *data = frame.data;
	for (int i = 0; i < size; ++i) {
    	left.data[i] = data[i*2];       // Y1   Y2
    	right.data[i] = data[i*2 + 1];  //    U    V
	}
	cv::imshow("left", left);
	cv::imshow("right", right);
    // 1フレームキャプチャ
    //cap >> frame;
    //if (!cap.read(frame))
    //{
    //    std::cout << "ERROR: cannot capture." << std::endl;
    //    break;
    //}

    
    //キー待ち
    int inp_key = cv::waitKey(1);

    //入力あり?
    if (inp_key >= 0) {
        // [ESC] or 'Q' or 'q'
        if (inp_key == 27 || inp_key == 81 || inp_key == 113) break;

        // 'S' or 's'
        //else if(inp_key == 83 || inp_key == 115)
        //{
        //  //フレーム画像を保存する
        //  cv::imwrite(SAVE_FILE, frame);
        //}
    }
} //end of while

//ウィンドウ破棄
cv::destroyAllWindows();

return 0;

}`

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

I want to get left image and right image from mynt-eye s1030 using cv::VideoCapture.
Like this image.
Screenshot from 2019-12-03 15-54-36

@flinnna
Copy link

flinnna commented Dec 4, 2019

you can refer to code below.
Screenshot from 2019-12-04 16-07-18

#include "camera.hpp"

// https://stackoverflow.com/questions/10167534/
// how-to-find-out-what-type-of-a-mat-object-is-with-mattype-in-opencv
/*
std::string type2str(int type) {
    std::string r;

    uchar depth = type & CV_MAT_DEPTH_MASK;
    uchar chans = 1 + (type >> CV_CN_SHIFT);

    switch ( depth ) {
        case CV_8U:  r = "8U"; break;
        case CV_8S:  r = "8S"; break;
        case CV_16U: r = "16U"; break;
        case CV_16S: r = "16S"; break;
        case CV_32S: r = "32S"; break;
        case CV_32F: r = "32F"; break;
        case CV_64F: r = "64F"; break;
        default:     r = "User"; break;
    }

    r += "C";
    r += (chans+'0');

    return r;
}
*/

int main(int argc, char const *argv[]) {
    int index = 0;
    if (argc >= 2) {
        try {
            index = std::stoi(argv[1]);
        } catch (...) {
            std::cout << "Warning: Can't set index: " << argv[1] << std::endl;
        }
    }
    Camera cam(index);
    if (!cam.IsOpened()) {
        std::cerr << "Error: Open camera failed" << std::endl;
        return 1;
    }
    std::cout << "\033[1;32mPress ESC/Q to terminate\033[0m\n";

    //std::cout << cv::getBuildInformation();

    // cv::VideoCaptureProperties:
    // http://docs.opencv.org/master/d4/d15/group__videoio__flags__base.html#gaeb8dd9c89c10a5c63c139bf7c4f5704d

    // For get raw camera data with v4l2
    std::cout << "CAP_PROP_CONVERT_RGB disabled: "
        << cam.Set(cv::CAP_PROP_CONVERT_RGB, 0)
        << std::endl;
    std::cout << "CAP_PROP_FORMAT: " <<
        cam.Get(cv::CAP_PROP_FORMAT) << std::endl;

    std::cout << std::flush;

    //cv::Mat frame;
    cv::Mat left, right;
    cam.Capture([&cam/*, &frame*/, &left, &right](
            const cv::Mat& raw, const cv::Mat& depthmap) {
        //std::cout << "type: " << type2str(raw.type()) << std::endl;
        /*
        cv::cvtColor(raw, frame, cv::COLOR_YUV2BGR_YUY2);
        cam.DrawInfo(frame);
        cv::imshow("camera", frame);
        */

        // Split raw data to two images
        const int &w = raw.cols, &h = raw.rows;
        const int size = w * h;

        if (left.cols != w || left.rows != h || left.type() != CV_8UC1)
            left = cv::Mat(h, w, CV_8UC1);
        if (right.cols != w || right.rows != h || right.type() != CV_8UC1)
            right = cv::Mat(h, w, CV_8UC1);

        unsigned char *data = raw.data;
        std::cout << "type: " << raw.data[0] << std::endl;
        for (int i = 0; i < size; ++i) {
            left.data[i] = data[i*2];       // Y1   Y2
            right.data[i] = data[i*2 + 1];  //    U    V
        }
        cv::imshow("left", left);
        cv::imshow("right", right);

        char key = (char) cv::waitKey(10);
        return !(key == 27 || key == 'q' || key == 'Q'); // ESC/Q
    });

    return 0;
}

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

what is camera.hpp?

@flinnna
Copy link

flinnna commented Dec 4, 2019

camera.hpp

#ifndef CAMERA_HPP_
#define CAMERA_HPP_
#pragma once

#include <functional>
#include <iostream>
#include <sstream>

#include <opencv2/opencv.hpp>

class Camera {
public:
    using VideoCapture = cv::VideoCapture;
    using FrameCallback = std::function<bool(const cv::Mat&, const cv::Mat&)>;

    Camera(int index = 0)
            : cap_(new VideoCapture(std::move(index))),
#ifdef USE_OPENNI
              use_openni_(index == cv::CAP_OPENNI || index == cv::CAP_OPENNI2),
#endif
              fps_(-1) {
        int flag = 0;
#ifdef USE_OPENNI
        if (use_openni_) {
            flag = cv::CAP_OPENNI_IMAGE_GENERATOR;
            Set(cv::CAP_OPENNI_IMAGE_GENERATOR_OUTPUT_MODE, cv::CAP_OPENNI_VGA_30HZ);
        }
#endif
        std::cout << "Capture frame width: " << Get(flag + cv::CAP_PROP_FRAME_WIDTH)
            << ", height: " << Get(flag + cv::CAP_PROP_FRAME_HEIGHT)
            << std::endl;
        fps_ = Get(flag + cv::CAP_PROP_FPS);
        std::cout << "Capture fps: " << fps_ << std::endl
#ifdef USE_OPENNI
            << "Use OpenNI: " << use_openni_ << std::endl
#endif
            << std::endl;
    }
    virtual ~Camera() {}

    bool UseOpenNI() {
#ifdef USE_OPENNI
        return use_openni_;
#else
        return false;
#endif
    }

    double Get(int prop_id) const {
        return cap_->get(prop_id);
    }

    bool Set(int prop_id, double value) {
        return cap_->set(prop_id, value);
    }

    bool IsOpened() {
#ifdef USE_OPENNI
        return use_openni_ || cap_->isOpened();
#else
        return cap_->isOpened();
#endif
    }

    void Preview(FrameCallback callback = nullptr) {
        cv::namedWindow("camera", 1);
        Capture([&callback](const cv::Mat& frame, const cv::Mat& depthmap) {
            cv::imshow("camera", frame);
            if (callback && !callback(frame, depthmap)) {
                // return false to break
                return false;
            }
            // return false to break if ESC/Q
            char key = (char) cv::waitKey(30);
            return !(key == 27 || key == 'q' || key == 'Q');
        });
    }

    // callback return true to continue and false to break
    void Capture(FrameCallback callback) {
        if (!callback) {
            std::cerr << "ERROR: Null FrameCallback\n";
            return;
        }

        cv::Mat frame;
        cv::Mat depthmap;
        double t;
        for (;;) {
            t = (double)cv::getTickCount();

#ifdef USE_OPENNI
            if (use_openni_) {
                cap_->grab();

                cap_->retrieve(depthmap, cv::CAP_OPENNI_DEPTH_MAP);
                cap_->retrieve(frame, cv::CAP_OPENNI_BGR_IMAGE);
                //cap_->retrieve(frame, cv::CAP_OPENNI_GRAY_IMAGE);
            } else {
                cap_->read(frame);
            }
#else
            cap_->read(frame);
#endif

            if (frame.empty()) {
                std::cerr << "ERROR: Blank frame grabbed\n";
                break;
            }

            bool ok = callback(frame, depthmap);

            t = (double)cv::getTickCount() - t;
            fps_ = cv::getTickFrequency() / t;
            //std::cout << "fps: " << fps_ << std::endl;

            if (!ok) break;
        }
    }

    double FPS() const {
        return fps_;
    }

    std::string ExtraInfo() const {
        std::ostringstream info;
        info << "FPS: " << fps_;
        return info.str();
    }

    void DrawInfo(const cv::Mat& im) const {
        using namespace std;
        int w = im.cols, h = im.rows;
        // topLeft: width x height
        {
            ostringstream ss;
            ss << w << "x" << h;
            string text = ss.str();

            int baseline = 0;
            cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN,
                1, 1, &baseline);

            cv::putText(im, text, cv::Point(5, 5 + textSize.height),
                cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255,0,255));
        }
        // topRight: fps
        {
            ostringstream ss;
            ss << "FPS: " << fps_;
            string text = ss.str();

            int baseline = 0;
            cv::Size textSize = cv::getTextSize(text, cv::FONT_HERSHEY_PLAIN,
                1, 1, &baseline);

            cv::putText(im, text,
                cv::Point(w - 5 - textSize.width, 5 + textSize.height),
                cv::FONT_HERSHEY_PLAIN, 1, cv::Scalar(255,0,255));
        }
    }

private:
    std::unique_ptr<VideoCapture> cap_;
#ifdef USE_OPENNI
    bool use_openni_;
#endif
    double fps_;
};

#endif  // CAMERA_HPP_

@fukamike
Copy link
Author

fukamike commented Dec 4, 2019

Thank you for your adovice.
I was able to get images.
Screenshot from 2019-12-04 18-51-33

@buchi77
Copy link

buchi77 commented Jan 6, 2020

hi,i copy and paste.
but it doesn't run.

721920 is stored in raw.cols
1 is stored in raw.rows

is this normal?

@jyzhong
Copy link

jyzhong commented Mar 26, 2021

Thank you for your adovice.
I was able to get images.
Screenshot from 2019-12-04 18-51-33

hello, i try what you did. but i failed. The result just like your second picture. can you give me some advice?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants