error in implementation of dct in opencv - c++

why the following errors occur when i try to implement dct in opencv?
Assertion failed (type == CV_32FC1 || type == CV_64FC1) in dct,
here is the code:
#include <cv.h>
#include "opencv2/imgproc/imgproc.hpp"
#include <highgui.h>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat image,dimage(image);
image = imread( "lena.jpg", 1 );
if( !image.data )
{
printf( "No image data \n" );
return -1;
}
namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
imshow( "Display Image", image );
dimage=Mat::zeros(image.rows,image.cols,CV_32F);
dct(image, dimage, DCT_INVERSE == 0 );
namedWindow( "DCT Image", CV_WINDOW_AUTOSIZE );
imshow( "DCT image", dimage );
waitKey(0);
return 0;
}

you have to convert your image from uchar to float first (and maybe back to uchar later):
// also please use the c++ headers, not the old c-ones !
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
Mat image = imread( "lena.jpg", 0 ); // grayscale
Mat fimage;
image.convertTo(fimage, CV_32F, 1.0/255); // also scale to [0..1] range (not mandatory)
// you're lucky with lena (512x512), for odd sizes, you have to
// pad it to pow2 size, or use dft() instead:
Mat dimage;
dct( fimage, dimage );
// process dimage,
// then same way back:
dct( dimage, dimage, DCT_INVERSE );
dimage.convertTo(image, CV_8U); // maybe scale back to [0..255] range (depending on your processing)
imshow("result",image);
waitKey();

Related

Displaying Multiple Images on Single window with OpenCV 3.0 and MSVS 12

i am new to opencv as well as to c++ and currently working on a program that requires me to display multiple images with opencv version 3.0 and visual studio 12. i am working on the following codes but it did not work. I would like to ask on how can i solve the problem.
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
//Image Reading
IplImage* img1 = cvLoadImage( "ball.jpg" );
IplImage* img2 = cvLoadImage( "ball.jpg" );
IplImage* img3 = cvLoadImage( "ball.jpg" );
IplImage* img4 = cvLoadImage( "ball.jpg" );
int dstWidth=img1->width+img1->width;
int dstHeight=img1->height+img1->height;
IplImage* dst=cvCreateImage(cvSize(dstWidth,dstHeight),IPL_DEPTH_8U,3);
// Copy first image to dst
cvSetImageROI(dst, cvRect(0, 0,img1->width,img1->height) );
cvCopy(img1,dst,NULL);
cvResetImageROI(dst);
// Copy second image to dst
cvSetImageROI(dst, cvRect(img2->width, 0,img2->width,img2->height) );
cvCopy(img2,dst,NULL);
cvResetImageROI(dst);
// Copy third image to dst
cvSetImageROI(dst, cvRect(0, img3->height,img3->width,img3->height) );
cvCopy(img3,dst,NULL);
cvResetImageROI(dst);
// Copy fourth image to dst
cvSetImageROI(dst, cvRect(img4->width, img4->height,img4->width,img4->height) );
cvCopy(img4,dst,NULL);
cvResetImageROI(dst);
//show all in a single window
cvNamedWindow( "Example1", CV_WINDOW_AUTOSIZE );
cvShowImage( "Example1", dst );
cvWaitKey(0);
}
Here's how you can do it with C++ API, if all images have the same size:
int main(int argc, char* argv[])
{
cv::Mat input1 = cv::imread("C:/StackOverflow/Input/Lenna.png");
cv::Mat input2 = cv::imread("C:/StackOverflow/Input/Lenna.png");
cv::Mat input3 = cv::imread("C:/StackOverflow/Input/Lenna.png");
cv::Mat input4 = cv::imread("C:/StackOverflow/Input/Lenna.png");
int width = 2*input1.cols; // width of 2 images next to each other
int height = 2*input1.rows; // height of 2 images over reach other
cv::Mat inputAll = cv::Mat(height, width, input1.type());
cv::Rect subImageROI = cv::Rect(0, 0, input1.cols, input1.rows);
// copy to subimage:
input1.copyTo(inputAll(subImageROI));
// move to 2nd image ROI position:
subImageROI.x = input1.cols;
input2.copyTo(inputAll(subImageROI));
subImageROI.x = 0;
subImageROI.y = input1.rows;
input3.copyTo(inputAll(subImageROI));
subImageROI.x = input1.cols;
subImageROI.y = input1.rows;
input4.copyTo(inputAll(subImageROI));
cv::imshow("input", inputAll);
cv::waitKey(0);
return 0;
}

Stereo with openCV

I try to find the distance between camera and an object,so I use two different cameras (stereo). I use the program in opencv samples .
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/contrib/contrib.hpp"
#include <stdio.h>
#include <string.h>
#include<iostream>
using namespace cv;
const char *windowDisparity = "Disparity";
int main( )
{
Size S(640,360);
Mat threshold2,threshold1;
Mat imgLeft = imread( "lift.jpg", CV_LOAD_IMAGE_GRAYSCALE );
Mat imgRight = imread("right.jpg", CV_LOAD_IMAGE_GRAYSCALE );
resize(imgLeft,imgLeft,S);
Mat imgDisparity16S = Mat( imgLeft.rows, imgLeft.cols, CV_16S );
Mat imgDisparity8U = Mat( imgRight.rows, imgRight.cols, CV_8UC1 );
int ndisparities = 16*5;
int SADWindowSize = 21;
StereoBM sbm( StereoBM::BASIC_PRESET,ndisparities,SADWindowSize );
sbm( imgLeft, imgRight, imgDisparity16S, CV_16S );
double minVal; double maxVal;
minMaxLoc( imgDisparity16S, &minVal, &maxVal );
printf("Min disp: %f Max value: %f \n", minVal, maxVal);
imgDisparity16S.convertTo( imgDisparity8U, CV_8UC1, 255/(maxVal - minVal));
namedWindow( windowDisparity, WINDOW_NORMAL );
imshow( windowDisparity, imgDisparity8U );
imshow( "left", imgLeft );
imshow( "right", imgRight );
imwrite("SBM_sample.png", imgDisparity16S);
waitKey(0);
return 0;
}
my problem is that I can't find the depth Z between object and camera
Maybe try to convert disparity to 3D points using cv::reprojectImageTo3D() or cv::perspectiveTransform() for sparse set of points.

opencv stereo vision depth map, code does not work

I am studying on stereo vision depth map and I am using the opencv library.I wrote a program to obtain depth map. But when program was run I obtained an empty depth map frame.can anybody help me please, what is wrong ? code are shown in below;
#include <opencv/highgui.h>
#include <opencv/cv.h>
#include <stdio.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <math.h>
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/contrib/contrib.hpp>
int main()
{
IplImage* img1 = cvLoadImage("/home/sezen/Masaüstü/imR.png");
IplImage* img2 = cvLoadImage("/home/sezen/Masaüstü/imL.png");
IplImage *rimage = cvCreateImage(
cvSize( img1->width, img1->height ), IPL_DEPTH_8U, 1 );
cvCvtColor( img1, rimage, CV_RGB2GRAY );
IplImage *limage = cvCreateImage(
cvSize( img2->width, img2->height ), IPL_DEPTH_8U, 1 );
cvCvtColor( img2, limage, CV_RGB2GRAY );
cvNamedWindow( "Right", CV_WINDOW_AUTOSIZE );
cvShowImage( "Right", rimage );
cvNamedWindow( "Left", CV_WINDOW_AUTOSIZE );
cvShowImage("Left", limage);
CvMat *matr = cvCreateMat(rimage->height,rimage->width,CV_8UC1 );
CvMat *matl = cvCreateMat(limage->height,limage->width,CV_8UC1 );
CvMat* disp = cvCreateMat(rimage->height,rimage->width,CV_16S);
CvMat* vdisp = cvCreateMat(rimage->height,rimage->width,CV_16S);
cvConvert( rimage, matr );
cvConvert( limage, matl );
CvStereoBMState *BMState = cvCreateStereoBMState();
assert(BMState != 0);
BMState->preFilterSize=21;
BMState->preFilterCap=31;
BMState->SADWindowSize=21;
BMState->minDisparity=0;
BMState->numberOfDisparities=128;
BMState->textureThreshold=10;
BMState->uniquenessRatio=15;
cvFindStereoCorrespondenceBM( matr, matl, disp, BMState);
cvNormalize(disp, vdisp, 0, 255, CV_MINMAX);
cvShowImage("depthmap", vdisp);
cvWaitKey(0);
return 0;
}
Here's a code for disparity map using C++ API. Final image that you normalize should be of type CV_8UC1.
Mat img1, img2, g1, g2;
Mat disp, disp8;
img1 = imread("leftImage.jpg");
img2 = imread("rightImage.jpg");
cvtColor(img1, g1, CV_BGR2GRAY);
cvtColor(img2, g2, CV_BGR2GRAY);
StereoBM sbm;
sbm.state->SADWindowSize = 9;
sbm.state->numberOfDisparities = 112;
sbm.state->preFilterSize = 5;
sbm.state->preFilterCap = 61;
sbm.state->minDisparity = -39;
sbm.state->textureThreshold = 507;
sbm.state->uniquenessRatio = 0;
sbm.state->speckleWindowSize = 0;
sbm.state->speckleRange = 8;
sbm.state->disp12MaxDiff = 1;
sbm(g1, g2, disp);
normalize(disp, disp8, 0, 255, CV_MINMAX, CV_8U);
imshow("left", img1);
imshow("right", img2);
imshow("disp", disp8);
I can only add that structure of OpenCV namespaces and classes changes every year.
I placed below working source code for OpenCV 3.4.0
#include <Windows.h>
#include <Vfw.h>
#include <string>
#include <iostream>
#include "opencv2\core\core.hpp"
#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\imgcodecs\imgcodecs.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\calib3d\calib3d.hpp"
using namespace std;
using namespace cv;
int _tmain(int argc, _TCHAR* argv[])
{
Mat im_left=imread("right.png");
Mat im_right=imread("left.png");
cv::Size imagesize = im_left.size();
cv::Mat disparity_left=cv::Mat(imagesize.height,imagesize.width,CV_16S);
cv::Mat disparity_right=cv::Mat(imagesize.height,imagesize.width,CV_16S);
cv::Mat g1,g2,disp,disp8;
cv::cvtColor(im_left,g1,cv::COLOR_BGR2GRAY);
cv::cvtColor(im_right,g2,cv::COLOR_BGR2GRAY);
cv::Ptr<cv::StereoBM> sbm = cv::StereoBM::create(0,21);
sbm->setDisp12MaxDiff(1);
sbm->setSpeckleRange(8);
sbm->setSpeckleWindowSize(9);
sbm->setUniquenessRatio(0);
sbm->setTextureThreshold(507);
sbm->setMinDisparity(-39);
sbm->setPreFilterCap(61);
sbm->setPreFilterSize(5);
sbm->compute(g1,g2,disparity_left);
normalize(disparity_left, disp8, 0, 255, CV_MINMAX, CV_8U);
cv::namedWindow("Left",CV_WINDOW_FREERATIO);
cv::imshow("Left", im_left);
cv::namedWindow("Right",CV_WINDOW_FREERATIO);
cv::imshow("Right", im_right);
cv::namedWindow("Depth map",CV_WINDOW_FREERATIO);
cv::imshow("Depth map", disp8);
cv::waitKey(0);
return 0;
}
For me it worked slightly different with the init of the stereoBM object
Ptr<StereoBM> sbm = cv::StereoBM::create(16, 5);
sbm->setDisp12MaxDiff(1);
sbm->setSpeckleRange(8);
sbm->setSpeckleWindowSize(0);
sbm->setUniquenessRatio(0);
sbm->setTextureThreshold(507);
sbm->setMinDisparity(-39);
sbm->setPreFilterCap(61);
sbm->setPreFilterSize(5);
sbm->compute(src1, src2, disp);
I edited the code to my needs, I added the camera one and two, and reading from them.
Then, made the Depth map. Thanks hope its helpful.
#include <string>
#include <iostream>
#include <opencv2/opencv.hpp>
#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgcodecs/imgcodecs.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/calib3d/calib3d.hpp"
using namespace std;
using namespace cv;
int main()
{
VideoCapture leftCam(0); //lets say 0 is left, 1 is right
if (leftCam.isOpened() == false){cout << "error: Webcam connect unsuccessful\n"; return(0); }
VideoCapture rightCam(1); //lets say 0 is left, 1 is right
if (rightCam.isOpened() == false){cout << "error: Webcam connect unsuccessful\n"; return(0); }
Mat left, right;
Mat leftClone, rightClone;
char charCheckForEscKey = 0;
while ( charCheckForEscKey != 27 && leftCam.isOpened() )
{
leftCam.read(left);
if (left.empty()){cout << "No frame to read" << endl; break;}
leftClone = left.clone(); //copy from the left camera
imwrite("left.png", leftClone); // write it to screenshot.png in this directory
rightCam.read(right);
if (right.empty()){cout << "No frame to read" << endl; break;}
rightClone = right.clone(); //copy from the left camera
imwrite("right.png", rightClone); // write it to screenshot.png in this directory
Mat im_left = imread("left.png"); //left cam picture
Mat im_right = imread("right.png"); // right cam picture
Size imagesize = im_left.size();
Mat disparity_left= Mat(imagesize.height,imagesize.width,CV_16S);
Mat disparity_right=Mat(imagesize.height,imagesize.width,CV_16S);
Mat g1,g2,disp,disp8;
cvtColor(im_left,g1, COLOR_BGR2GRAY);
cvtColor(im_right,g2, COLOR_BGR2GRAY);
Ptr<cv::StereoBM> sbm = StereoBM::create(0,21);
sbm->setDisp12MaxDiff(1);
sbm->setSpeckleRange(8);
sbm->setSpeckleWindowSize(9);
sbm->setUniquenessRatio(0);
sbm->setTextureThreshold(507);
sbm->setMinDisparity(-39);
sbm->setPreFilterCap(61);
sbm->setPreFilterSize(5);
sbm->compute(g1,g2,disparity_left);
normalize(disparity_left, disp8, 0, 255, NORM_MINMAX, CV_8U);
namedWindow("Left", WINDOW_AUTOSIZE);
imshow("Left", im_left);
namedWindow("Right", WINDOW_AUTOSIZE);
imshow("Right", im_right);
namedWindow("Depth map", WINDOW_AUTOSIZE);
imshow("Depth map", disp8);
namedWindow("Left Cloned", WINDOW_FREERATIO);
imshow("Left Cloned", leftClone); // left is the left pic taken from camera 0
charCheckForEscKey = waitKey(1);
}
return(0);
}
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
#include<opencv2/calib3d.hpp>
int main()
{
cv::Mat leftimg =cv::imread("leftimage.jpg");
cv::Mat rightimg = cv::imread("rightimage.jpg");
cv::Mat disparity_left=cv::Mat(leftimg.size(),leftimg.type());
cv::Mat disparity_right=cv::Mat(rightimg.size(),rightimg .type());
cv::Mat g1,g2,disp,disp8;
cv::cvtColor(leftimg,g1,cv::COLOR_BGR2GRAY);
cv::cvtColor(rightimg,g2,cv::COLOR_BGR2GRAY);
cv::Ptr<cv::StereoBM> sbm = cv::createStereoBM(16,21);
sbm->setDisp12MaxDiff(1);
sbm->setSpeckleRange(8);
sbm->setSpeckleWindowSize(9);
sbm->setUniquenessRatio(0);
sbm->setTextureThreshold(507);
sbm->setMinDisparity(-39);
sbm->setPreFilterCap(61);
sbm->setPreFilterSize(5);
sbm->compute(g1,g2,disparity_left);
normalize(disparity_left, disp8, 0, 255, CV_MINMAX, CV_8U);
}

OpenCV: record footage in one window and Display the same video in 2nd window but with contours only

I want to capture a video and display it on one window and have second window in which contours are displayed simultaneous. I am struggling with how to have the processed video displayed in the second window. Please analyze my code and suggest a solution or indicate where am going wrong maybe give me some directions to an online tutorial or sources. Thanks.
#include "iostream"
#include<opencv\cv.h>
#include<opencv\highgui.h>
#include<opencv\ml.h>
#include<opencv\cxcore.h>
#include <iostream>
#include <vector>
#include <string>
#include <opencv2/core/core.hpp> // Basic OpenCV structures (cv::Mat)
#include <opencv2/highgui/highgui.hpp> // Video write
using namespace cv;
using namespace std;
Mat image; Mat image_gray; Mat image_gray2; Mat threshold_output;
Mat frame;
int thresh=100, max_thresh=255;
int main(int argc, char** argv) {
//Capture Video
VideoCapture capCam(1);
if (!capCam.isOpened()){
cout<<"ERROR: Failed to Initialize Camera"<<endl;
return 1;
}
else{
cout<<"Camera Initialized"<<endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
imshow(ImputFootage, frame);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
imshow(OutputFootage, frame);
while(1){
capCam>> frame;
imshow("Source", frame);
return(1);
if(capCam.read(ImputFootage)){
//Convert Image to gray & blur it
cvtColor( image,
image_gray,
CV_BGR2GRAY );
blur( image_gray,
image_gray2,
Size(3,3) );
//Threshold Gray&Blur Image
threshold(image_gray2,
threshold_output,
thresh,
max_thresh,
THRESH_BINARY);
//2D Container
vector<vector<Point>> contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output,
contours, // a vector of contours
CV_RETR_EXTERNAL,// retrieve the external contours
CV_CHAIN_APPROX_NONE,
Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(),CV_8U,Scalar(255));
drawContours(result,contours,
-1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
}
}
char CheckForEscKey = waitKey(10);
return 1;
}
You should call imshow("Processed", result); after calling drawContours
You were trying to show frames even before they were captured with camera. Compiler was not giving you error because Mat were declared ,but they were without value (null), Moreover you were trying to display Mat image, but what you capture from camera is Mat frame. Also, you lack exit (esc sequence, and your wait key was OUT of camera loop.
Anyway, here is your code (rewritten), I hope this is what you wanted.
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cstdio>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
using namespace cv;
Mat image;
Mat image_gray;
Mat image_gray2;
Mat threshold_output;
Mat frame;
int thresh = 100, max_thresh = 255;
int main(int argc, char** argv)
{
//Capture Video
VideoCapture capCam(0);
if (!capCam.isOpened())
{
cout << "ERROR: Failed to Initialize Camera" << endl;
return 1;
}
else
{
cout << "Camera Initialized" << endl;
}
//Create Window
char* ImputFootage = "Source";
namedWindow(ImputFootage, CV_WINDOW_AUTOSIZE);
char* OutputFootage = "Processed";
namedWindow(OutputFootage, CV_WINDOW_AUTOSIZE);
while (1)
{
capCam >> frame;
imshow(ImputFootage, frame);
if (capCam.read(frame))
{
//Convert Image to gray & blur it
cvtColor(frame, image_gray, CV_BGR2GRAY);
blur(image_gray, image_gray2, Size(3, 3));
//Threshold Gray&Blur Image
threshold(image_gray2, threshold_output, thresh, max_thresh, THRESH_BINARY);
//2D Container
vector<vector<Point> > contours;
//Fnd Countours Points, (Imput Image, Storage, Mode1, Mode2, Offset??)
findContours(threshold_output, contours, // a vector of contours
CV_RETR_EXTERNAL, // retrieve the external contours
CV_CHAIN_APPROX_NONE, Point(0, 0)); // all pixels of each contours
// Draw black contours on a white image
Mat result(threshold_output.size(), CV_8U, Scalar(255));
drawContours(result, contours, -1, // draw all contours
Scalar(0), // in black
2); // with a thickness of 2
imshow(OutputFootage, result);
char CheckForEscKey = waitKey(10);
//If the key pressed by user is Esc(ASCII is 27) then break out of the loop
if (CheckForEscKey == 27)
{
break;
}
}
}
return 0;
}

How can I convert a cv::Mat to a gray scale in OpenCv?

How can I convert a cv::Mat to a gray scale?
I am trying to run drawKeyPoints func from opencv, however I have been getting an Assertion Filed error. My guess is that it needs to receive a gray scale image rather than a color image in the parameter.
void SurfDetector(cv::Mat img){
vector<cv::KeyPoint> keypoints;
cv::Mat featureImage;
cv::drawKeypoints(img, keypoints, featureImage, cv::Scalar(255,255,255) ,cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
cv::namedWindow("Picture");
cv::imshow("Picture", featureImage);
}
Using the C++ API, the function name has slightly changed and it writes now:
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat greyMat, colorMat;
cv::cvtColor(colorMat, greyMat, CV_BGR2GRAY);
The main difficulties are that the function is in the imgproc module (not in the core), and by default cv::Mat are in the Blue Green Red (BGR) order instead of the more common RGB.
OpenCV 3
Starting with OpenCV 3.0, there is yet another convention.
Conversion codes are embedded in the namespace cv:: and are prefixed with COLOR.
So, the example becomes then:
#include <opencv2/imgproc/imgproc.hpp>
cv::Mat greyMat, colorMat;
cv::cvtColor(colorMat, greyMat, cv::COLOR_BGR2GRAY);
As far as I have seen, the included file path hasn't changed (this is not a typo).
May be helpful for late comers.
#include "stdafx.h"
#include "cv.h"
#include "highgui.h"
using namespace cv;
using namespace std;
int main(int argc, char *argv[])
{
if (argc != 2) {
cout << "Usage: display_Image ImageToLoadandDisplay" << endl;
return -1;
}else{
Mat image;
Mat grayImage;
image = imread(argv[1], IMREAD_COLOR);
if (!image.data) {
cout << "Could not open the image file" << endl;
return -1;
}
else {
int height = image.rows;
int width = image.cols;
cvtColor(image, grayImage, CV_BGR2GRAY);
namedWindow("Display window", WINDOW_AUTOSIZE);
imshow("Display window", image);
namedWindow("Gray Image", WINDOW_AUTOSIZE);
imshow("Gray Image", grayImage);
cvWaitKey(0);
image.release();
grayImage.release();
return 0;
}
}
}