OpenCV C++ - Video saved using VideoWritter cannot be opened - c++

So I am trying to edit all the frames from input video and than save them to the output. The saved video appears and has the proper filesize but can't open and the imshow inside the while doesn't show the frames at all (only a blank window). I've tried numerous codecs (H264,MJPG,MPEG,MPV4,XVID,CVID) and non of them make it work. What could be the problem? Also, the first function is for converting RGB to YUV and returning the gray channel, while the second one works with HPF and LPF. These functions work on individual images so I don't think they are the problem.
#include <opencv2\opencv.hpp>
#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
Mat KonverzijaRGB2YUV(Mat ulazniFrejm){
int width = ulazniFrejm.cols;
int height = ulazniFrejm.rows;
Mat konvertovan(height, width, CV_8UC3, Scalar(0,0,0));
for(int i=0; i<width; i++){
for(int j=0; j<height; j++){
double R = ulazniFrejm.at<Vec3b>(j,i).val[0];
double G = ulazniFrejm.at<Vec3b>(j,i).val[1];
double B = ulazniFrejm.at<Vec3b>(j,i).val[2];
double Y = 0.299*R + 0.587*G + 0.114*B;
double U = 0.436*(B-Y) / (1-0.114);
double V = 0.615*(R-Y) / (1-0.299);
konvertovan.at<Vec3b>(j,i).val[0] = Y;
konvertovan.at<Vec3b>(j,i).val[1] = U;
konvertovan.at<Vec3b>(j,i).val[2] = V;
}
}
Mat Ykanal[3];
split (konvertovan, Ykanal);
Mat YkanalRGB;
cvtColor(Ykanal[0], YkanalRGB, CV_GRAY2RGB);
return YkanalRGB;
}
Mat Izostravanje(Mat ulazniFrejm){
Mat izostrena;
float valLaplas[] =
{ 0.,-1.,0.,
-1.,4.,-1.,
0.,-1.,0. };
Mat kernelLaplas(Size(3,3), CV_32FC1, valLaplas);
Mat Laplas;
filter2D(ulazniFrejm, Laplas, -1, kernelLaplas);
convertScaleAbs(Laplas, Laplas);
Mat Gaus;
GaussianBlur(ulazniFrejm, Gaus, Size(3,3), 0, 0);
addWeighted(Laplas, 1.4, Gaus, 1.0, 0, izostrena);
return izostrena;
}
int main(int argc, char** argv){
VideoCapture ulazniVideo("esmeralda.mp4");
int brojFrejmova = static_cast<int>(ulazniVideo.get(CV_CAP_PROP_FRAME_COUNT));
if(!ulazniVideo.isOpened()){
cout << "Video se ne moze otvoriti" << endl;
}
waitKey(1000);
Size frameSize = Size((int)ulazniVideo.get(CV_CAP_PROP_FRAME_WIDTH), (int)ulazniVideo.get(CV_CAP_PROP_FRAME_HEIGHT));
int fps = ulazniVideo.get(CV_CAP_PROP_FPS);
int ex = -1;
VideoWriter izlazniVideo;
izlazniVideo.open("esmeralda.mp4", ex, fps, frameSize, true);
int brojac = 0;
while(true){
Mat frame;
ulazniVideo >> frame;
Mat konvertovanFrejm;
konvertovanFrejm = KonverzijaRGB2YUV(frame);
Mat izostrenFrejm;
izostrenFrejm = Izostravanje(konvertovanFrejm);
if(frame.empty()){
break;
}
izlazniVideo << frame;
brojac++;
namedWindow("Video", CV_WINDOW_AUTOSIZE);
imshow("Video", izostrenFrejm);
int waitKey(1000/fps);
}
waitKey(0);
return 0;
}

Related

C++ OpenCV downsized videoCapture frame stretched and cropped

I am trying to get a calibration program for captured thermal video converted from python to C++, and the first step in the process is binning the pixels in the image down from 480x640 to 240x320, so pixel bins of 2x2. The returned image after binning (using the same logic from the correctly functioning python version) the image being returned is the left half of the image stretched across the width of the image, rather than giving the whole image only at the smaller resolution.
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <opencv2/video.hpp>
#include <opencv2/imgcodecs.hpp>
#include <iostream>
using namespace std;
using namespace cv;
Mat binImg(Mat);
int asInt(uint8_t);
uint8_t as8bit(int);
Mat rotate(Mat, double);
int main(int argc, char *argv[]){
VideoCapture cap(argv[1]);
int frameCount = cap.get(cv::CAP_PROP_FRAME_COUNT);
int frameWidth = cap.get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = cap.get(cv::CAP_PROP_FRAME_HEIGHT);
Mat buf [frameCount]; //create new array of Mat for the calibrated video
int fc = 0;
VideoWriter video("cppThermalTest.avi",CV_FOURCC('X','V','I','D'), 15, Size(240, 320), false); //create empty video #15fps, 320x240, isColor=false
while (fc < frameCount){
Mat frame(640, 480, CV_8UC1, Scalar(70));
cap >> frame;
Mat temp = binImg(frame);//bin the frame
imshow("test", temp);
imwrite("test.jpg", temp);
waitKey(0);
video.write(temp); //write the binned frame to the video
cout << fc << endl;
fc++;
}
cap.release();
video.release();
return 0;
}
Mat binImg(Mat frame){
int frameWidth = frame.cols / 2; //480 / 2
int frameHeight = frame.rows / 2; //640 / 2
cout << frameHeight << " " << frameWidth << endl;
Mat binFrame(frameHeight, frameWidth, CV_8UC1);
for(int i=0; i<binFrame.rows; i++){
for(int j=0; j<binFrame.cols; j++){
int ul = asInt(frame.at<uint8_t>((2*i),(2*j)));
int bl = asInt(frame.at<uint8_t>(((2*i)+1),(2*j)));
int ur = asInt(frame.at<uint8_t>((2*i), ((2*j)+1)));
int br = asInt(frame.at<uint8_t>(((2*i)+1),((2*j)+1)));
int avg = (ul + ur + bl + br) / 4;
binFrame.at<uint8_t>(i,j) = as8bit(avg); //set the matrix element to the new value
}
}
return binFrame;
}
int asInt(uint8_t val){
//convert unsigned 8 bit int to int
int temp = val;
return temp;
}
uint8_t as8bit(int val){
//convert int to unsigned 8 bit int
uint8_t temp = val;
return temp;
}
Mat rotate(Mat src, double angle){ //rotate function returning mat object with parametres imagefile and angle
Mat dst; //Mat object for output image file
Point2f pt(src.cols/2., src.rows/2.); //point from where to rotate
Mat r = getRotationMatrix2D(pt, angle, 1.0); //Mat object for storing after rotation
warpAffine(src, dst, r, Size(src.cols, src.rows)); ///applie an affine transforation to image.
return dst; //returning Mat object for output image file
}
After playing around with things for a while, I found that when doing "at" calls, specifying 0 as a third parameter (e.g. binFrame.at<uint8_t>(i,j, 0) = as8bit(avg);) fixes the issue.

OpenCV reading RGB Values. Values are not consistent for every run

When running this code with the same image and mask I occasionally get values that differ previously. For example
Normal/Expected Results
Abnormal Results
As can be seen in the two results I somehow receive negative RGB values. The Abnormal Results show up around every 5-8 runs for the exact same image with the exact same mask.
What do I need to change to prevent the occasional abnormal result?
#include <opencv2/opencv.hpp>
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <string>
using namespace cv;
using namespace std;
float get_color(Mat img,Mat &mask){
Mat img1 = img;
Mat hist;
int dims = 1;
int histSize = 255;
float hranges[] = { 0, 255 };
const float *ranges = {hranges};
calcHist(&img1,1,0,mask,hist, dims, &histSize, &ranges ,true ,false);
int sum=0;
for(int i = 0;i<256;i++){
sum += hist.at<float>(i,0);
}
Mat weights = hist/sum;
float hist_avg=0.0;
for(int i = 0;i<256;i++){
hist_avg += i*weights.at<float>(i,0);
}
return hist_avg;
}
int main(int argc, char** argv){
Mat aa = imread("/Users/dnguyen/Desktop/snapshot207042/pic.jpg", CV_LOAD_IMAGE_COLOR);
vector<Mat> bgr;
split(aa, bgr);
Mat b = bgr[0];
Mat g = bgr[1];
Mat r = bgr[2];
for(unsigned int i=1;i<23;i++){
stringstream ss;
ss << i;
string str = ss.str();
string file_name = "/Users/dnguyen/Desktop/okay/data/card_masks/"+str+"_mask.png";
Mat mask = imread(file_name,0);
Mat cc;
threshold(mask,cc,90,255,THRESH_BINARY);
float b_avg = get_color(b, cc);
float g_avg = get_color(g, cc);
float r_avg = get_color(r, cc);
cout << b_avg << ","<< g_avg << "," << r_avg << endl;
}
}

What is output from OpenCV's Dense optical flow (Farneback) function? Cpp

First of all sorry for my bad english.
So, im using dense optical flow, GunnarFarneback speciffically. The code works fine.
Here's the code:
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/video/tracking.hpp"
#include <vector>
#include <iostream>
using namespace std;
using namespace cv;
// Display the results of the matches
//
int main(int argc, char** argv)
{
cv::Mat res, img1, img2, img2Original, img2OriginalC;
cv::VideoWriter writer;
cv::VideoCapture cap;
//cv::VideoCapture cap("prueba1.mp4");
// cap.open(std::string(argv[1]));
cap.open(0);
cv::namedWindow("cat", cv::WINDOW_AUTOSIZE);
cap >> img1;
cvtColor(img1, img1, COLOR_BGR2GRAY);
double fps = cap.get(cv::CAP_PROP_FPS);
//cv::Size tamano((int)cap.get(cv::CAP_PROP_FRAME_WIDTH), (int)cap.get(cv::CAP_PROP_FRAME_HEIGHT));
Size S = Size((int) cap.get(CV_CAP_PROP_FRAME_WIDTH),(int) cap.get(CV_CAP_PROP_FRAME_HEIGHT));
writer.open("mouse.avi", CV_FOURCC('M', 'J', 'P', 'G'), fps, S);
for (;;) {
cap >> img2;
if (img2.empty()) break;
img2.copyTo(img2OriginalC);
cvtColor(img2, img2, COLOR_BGR2GRAY);
img2.copyTo(img2Original);
cv::calcOpticalFlowFarneback(img1, img2, res, .4, 1, 12, 2, 8, 1.2, 0);
for (int y = 0; y < img2.rows; y += 5) {
for (int x = 0; x < img2.cols; x += 5)
{
// get the flow from y, x position * 3 for better visibility
const Point2f flowatxy = res.at<Point2f>(y, x) * 1;
// draw line at flow direction
line(img2OriginalC, Point(x, y), Point(cvRound(x + flowatxy.x), cvRound(y + flowatxy.y)), Scalar(255, 0, 0));
// draw initial point
circle(img2OriginalC, Point(x, y), 1, Scalar(0, 0, 0), -1);
}
}
img2Original.copyTo(img1);
imshow("cat", img2OriginalC);
writer << img2OriginalC;
cout <<"Fps"<<endl;
cout <<fps<< endl;
for( int i=3; i>=0; i--)
{
//cout<< res << endl;
//return 0;
}
if (cv::waitKey(1) == 27) break;
}
cap.release();
return 0;
}
i think i know whats the output matrix but im not sure at all. Also,i dont know what does the values mean, finally does anyone knows how to use that output data??
Thanks

OpenCV Error : Assertion failed when using fitLine

I want to use the fitLine function to come up with a line to draw on my source image src_crop. I load the frame in my main() and call the drawLine().
But the code aborts with the following error :
Code:
#include "stdafx.h"
#include <fstream>
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <stdio.h>
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
using namespace std;
using namespace cv;
/// Global variables
Mat src_gray;
Mat src_crop;
Mat dst, detected_edges;
int edgeThresh = 1;
int lowThreshold = 27;
int const max_lowThreshold = 100;
int ratio = 3;
int kernel_size = 3;
char* window_name = "Edge Map";
int i,j;
void drawLine(int, void*)
{
vector<Vec4f> outline;
vector<Point2f> ssline;
int flag2 = 0;
/// Reduce noise with a kernel 3x3
blur(src_gray, detected_edges, Size(3, 3));
/// Canny detector
Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
/// Using Canny's output as a mask, we display our result
dst.create(detected_edges.size(), detected_edges.type());
dst = Scalar::all(0);
src_crop.copyTo(dst, detected_edges);
//namedWindow("Detected Edges", CV_WINDOW_AUTOSIZE);
//imshow("Detected Edges", detected_edges);
cvtColor(dst, dst, CV_BGR2GRAY);
for (j = 0; j < dst.cols; j++)
{
for (i = 0; i < dst.rows; i++)
{
if (Scalar(dst.at<uchar>(i,j)).val[0] >= 90)
{
//cout << "Hi";
flag2 = 1;
break;
}
}
if (flag2 == 1)
break;
}
int k = j;
int l = i;
for (j = k; j < dst.cols; j++)
{
Point2f ss = Point2f(l,j);
ssline.push_back(ss);
}
fitLine(ssline, outline, CV_DIST_L1, 0, 0.01, 0.01);
//imshow("Result", src_crop);
}
int main(int argc, char** argv)
{
/// Load an image
src = imread(s);
if (!src.data)
{
return -1;
}
/// Create a matrix of the same type and size as src (for dst)
//dst.create(src.size(), src.type());
src_crop = src;
/// Convert the image to grayscale
cvtColor(src_crop, src_gray, CV_BGR2GRAY);
/// Create a window
namedWindow(window_name, CV_WINDOW_AUTOSIZE);
/// Create a Trackbar for user to enter threshold
createTrackbar("Min Threshold:", window_name, &lowThreshold, max_lowThreshold, drawLine);
/// Show the image
drawLine(0, 0);
if (waitKey(30) >= 0) break;
return 0;
}
The code stops working at the point fitLine() is called. This I found by testing the code with printf statements.
Can anyone kindly help me solve the issue?
Aside the fact the your code won't compile, the issue is that you're passing to fitLine the parameter outline as a vector<Vec4f>, while it should be a Vec4f.
Change outline declaration as:
Vec4f outline;

OpenCV PointCloud from Depth map

I am trying to generate a point cloud with my Minoru3D stereo camera, but it does not work.
The generated points are definitely not correct.
The camera is correctly calibrated.
My rectified images(rec1, rec2), the disparity map(disp) and the depth map(depth):
And the pointcloud:
I create the depth image with reprojectImageTo3D and then read the points at every pixel.
Full Code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/contrib/contrib.hpp>
#include <opencv2/calib3d/calib3d.hpp>
#include "libcam.h"
#include <stdio.h>
#include <fstream>
using namespace cv;
using namespace std;
int main(int argc, char** argv) {
// The camera properties
int w = 640;
int h = 480;
int fps = 20;
// The images, which are proceeded
Mat img1, img2;
// The grayscale versions of the images
Mat gray1, gray2;
// The disparity and depth map
Mat disparity;
Mat depth(Size(h, w), CV_32FC3);
// The iplImage versions of the images used to get the images from the camera
IplImage *iplImg1 = cvCreateImage(cvSize(w, h), 8, 3), *iplImg2 = cvCreateImage(cvSize(w, h), 8, 3);
// The cameras
Camera cam1("/dev/video0", w, h, fps), cam2("/dev/video1", w, h, fps);
// Load the camera model
Mat CM1, CM2, D1, D2, R, T, E, F, R1, R2, P1, P2, Q;
FileStorage fs("data/stereocalib.yml", FileStorage::READ);
fs["CM1"] >> CM1;
fs["CM2"] >> CM2;
fs["D1"] >> D1;
fs["D2"] >> D2;
fs["R"] >> R;
fs["T"] >> T;
fs["E"] >> E;
fs["F"] >> F;
fs["R1"] >> R1;
fs["R2"] >> R2;
fs["P1"] >> P1;
fs["P2"] >> P2;
fs["Q"] >> Q;
fs.release();
Mat map1x = Mat(h, w, CV_32F);
Mat map1y = Mat(h, w, CV_32F);
Mat map2x = Mat(h, w, CV_32F);
Mat map2y = Mat(h, w, CV_32F);
initUndistortRectifyMap(CM1, D1, R1, P1, cvSize(w, h), CV_32FC1, map1x, map1y);
initUndistortRectifyMap(CM2, D2, R2, P2, cvSize(w, h), CV_32FC1, map2x, map2y);
// The rectified images
Mat imgU1 = Mat(img1.size(), img1.type()), imgU2 = Mat(img2.size(), img2.type());
Ptr<StereoBM> sbm = createStereoBM(16 * 10, 5);
while (true) {
// Get the images from the cameras
cam1.Update();
cam2.Update();
cam1.toIplImage(iplImg1);
cam2.toIplImage(iplImg2);
img1 = cvarrToMat(iplImg1);
img2 = cvarrToMat(iplImg2);
// Rectify
remap(img1, imgU1, map1x, map1y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
remap(img2, imgU2, map2x, map2y, INTER_LINEAR, BORDER_CONSTANT, Scalar());
// Convert the rectified images to grayscale images
cvtColor(imgU1, gray1, CV_BGR2GRAY);
cvtColor(imgU2, gray2, CV_BGR2GRAY);
// Create disparity map
sbm->compute(gray1, gray2, disparity);
// Create depth map
reprojectImageTo3D(disparity, depth, Q, true, CV_32F);
//imshow("img1", img1);
//imshow("img2", img2);
imshow("rec1", gray1);
imshow("rec2", gray2);
imshow("disp", disparity);
imshow("depth", depth);
int key = waitKey(10);
if (key == 'q') {
break;
}
else if (key == 's') {
stringstream output;
for (int x = 0; x < img1.rows; x++) {
for (int y = 0; y < img1.cols; y++) {
Point3f p = depth.at<Point3f>(x, y);
if(p.z >= 10000) continue; // Filter errors
output << p.x << "," << p.y << "," << p.z << endl;
}
}
ofstream outputFile("points");
outputFile << output.str();
outputFile.close();
cout << "saved" << endl;
}
else if (key == 'p') {
waitKey(0);
}
}
destroyAllWindows();
return 0;
}