OpenCV Error : Assertion failed when using fitLine - c++

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;

Related

Downsampling an image by 2, OpenCV

guys. Just for you know, I'm new to this environment, so if I do something wrong, feel free to warn me.
So, I was trying to create a basic algorithm for downsampling an image by an ancient technique. I'm new to OpenCV as well.
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <stdio.h>
#include <iostream>
using namespace std;
using namespace cv;
void filter2(const Mat &image, Mat &out)
{
// convert and split
Mat imgf;
image.convertTo(imgf, CV_32F, 1.0 / 255.0);
Mat chn[3];
split(imgf, chn);
Mat newchn[3];
// Resampling by 2
for (int dim = 0; dim < 3; dim++) {
Mat dummy2;
Mat dummy = chn[dim];
for (int i = 0; i < chn[dim].rows/2; i++) {
for (int j = 0; j < chn[dim].cols/2; j++) {
dummy2.at<double>(i,j) = dummy.at<double>(i*2,j*2);
}
}
dummy2 = newchn[dim];
}
// merge and convert
merge(newchn, 3, imgf);
imgf.convertTo(out, CV_8U, 255.0);
}
int main(int agra, char** argv) {
String fn = "eva_green.png";
if (agra > 1) fn = argv[1];
Mat image = imread(fn);
if (image.empty())
{
cerr << "No image";
return 1;
}
Mat result;
filter2(image, result);
imshow("org", image);
imshow("res", result);
waitKey(0);
return 0;
}
The "filter2" function does the job. What is wrong with my code?

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

Video very long time to load. Opencv

I'm a novice programmer. My experience is very small. Now I have a code to detected people. I use SVM classifier and a HOG descriptor. Video is very long to be loaded and processed. Please help me with this problem.
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <conio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
string filename = "Street.MP4";
VideoCapture capture(filename);
Mat frame;
//namedWindow("w", 1);
while (true)
{
capture >> frame;
if (frame.empty())
break;
Mat img, res;
Mat framecopy = frame.clone();
resize(framecopy, img, Size(2 * framecopy.cols, 2 * framecopy.rows));
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128);
Size winStride(4, 4);
HOGDescriptor hog(winSize, blockSize, blockStride, cellSize, nbins);
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
assert(hog.checkDetectorSize());
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights, 0.0, winStride, Size(), 1.05, 2., true);
resize(img, res, Size(framecopy.cols / 2, framecopy.rows / 2));
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(res, detection, Scalar(0, 0, 255), 2);
}
imshow("w", res);
waitKey(20); // waits to display frame
}
waitKey();
return 0;
}
Don't create the hog detector in each iteration.
try:
#include <assert.h>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <conio.h>
#include "opencv2/opencv.hpp"
using namespace cv;
using namespace std;
int main()
{
string filename = "Street.MP4";
VideoCapture capture(filename);
Mat frame;
//namedWindow("w", 1);
int nbins = 9;
Size cellSize(8, 8);
Size blockSize(16, 16);
Size blockStride(8, 8);
Size winSize(64, 128);
Size winStride(4, 4);
HOGDescriptor hog(winSize, blockSize, blockStride, cellSize, nbins);
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
assert(hog.checkDetectorSize());
while (true)
{
capture >> frame;
if (frame.empty())
break;
Mat img, res;
Mat framecopy = frame.clone();
resize(framecopy, img, Size(2 * framecopy.cols, 2 * framecopy.rows));
vector<Rect> locations;
vector<double> weights;
hog.detectMultiScale(img, locations, weights, 0.0, winStride, Size(), 1.05, 2., true);
resize(img, res, Size(framecopy.cols / 2, framecopy.rows / 2));
for (size_t i = 0; i < locations.size(); ++i)
{
Rect detection = locations[i];
detection.x /= 2;
detection.y /= 2;
detection.width /= 2;
detection.height /= 2;
rectangle(res, detection, Scalar(0, 0, 255), 2);
}
imshow("w", res);
waitKey(1); // waits to display frame
}
waitKey();
return 0;
}
But keep in mind that HoG detection is a quite expensive operation. What's the resolution of your images?

Gamma Correction with pow

I would use gamma correction to a image.
So, I have to pow every pixel intensity of my source image with a G = 0.6.
I have problem cause the destination image is completely wrong.
Maybe I have a casting problem when I take pixel from source image.
Here my code:
#include <opencv2/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <opencv2/imgproc/imgproc.hpp>
using namespace cv;
using namespace std;
int main() {
Mat src = imread("spine1.jpeg");
Mat dst = Mat(src.rows, src.cols, CV_8UC1);
cvtColor(src, src, CV_8UC1);
dst = Scalar(0);
for (int x = 0; x < src.rows; x++) {
for (int y = 0; y < src.cols; y++) {
int pixelValue = (int)src.at<uchar>(x, y);
dst.at<uchar>(x, y) = pow(pixelValue, 0.6);
}
}
namedWindow("Input", CV_WINDOW_AUTOSIZE);
namedWindow("Output", CV_WINDOW_AUTOSIZE);
imshow("Input", src);
imshow("Output", dst);
waitKey(0);
return 0;
}
Edit: change cvtColor(src, src, CV_8UC1); in cvtColor(src, src, COLOR_BGR2GRAY);
The call to cvtColor is wrong. You should use:
cvtColor(src, src, COLOR_BGR2GRAY);
Also, you can make your code much simpler, and less error prone:
#include <opencv2/opencv.hpp>
int main()
{
// Load the image as grayscale
cv::Mat1b src = cv::imread("path_to_img", cv::IMREAD_GRAYSCALE);
// Convert to double for "pow"
cv::Mat1d dsrc;
src.convertTo(dsrc, CV_64F);
// Compute the "pow"
cv::Mat1d ddst;
cv::pow(dsrc, 0.6, ddst);
// Convert back to uchar
cv::Mat1b dst;
ddst.convertTo(dst, CV_8U);
// Show results
imshow("SRC", src);
imshow("DST", dst);
waitKey();
return 0;
}

Detect number of objects using number of canny contours Opencv

I try to count the number of hearts in the following image by using a canny edge detection algorithm and contours.
But after the contours I have gotten image like this and it has contoured 4 instead of 3. What kind of method I have to follow to count any number of object different shapes of deck card pack. I only need number of symbols in the middle.
Here is my c++ code
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/core/core.hpp>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
Mat src;
Mat dst;
Mat canny_output;
//this is function for loading the image
void loadImage(char* source){
Mat tmp;
/// Load source image and convert it to gray
src = imread( source, 1 );
/// Convert image to gray and blur it
cvtColor( src, tmp, CV_RGB2GRAY );
//blur( src_gray, src_gray, Size(3,3) );
bitwise_not( tmp, src);
}
void clearImage(){
int i,j;
int r = 10;
Mat clone;
src.copyTo(clone);
for(i = 0;i < src.rows;++i){
j = 0;
clone.at<Vec3b>(i,j) = Vec3b(0,0,0);
for(j = 0;j < src.cols;++j){
if(src.at<cv::Vec3b>(i,j) == cv::Vec3b(255,255,255)){
rectangle(
clone,
cv::Point(i-r, j),
cv::Point(i+r, j+r),
cv::Scalar(255, 255, 255)
);
}
}
}
}
void detectImages(){
int thresh = 100;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
Canny( src, canny_output, thresh, thresh*2, 3 );
/// Find contours
findContours( canny_output, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE, Point(0, 0) );
cout<<(hierarchy.size())<<endl;
}
//corpping and resizing the image
void corpResizeImage(){
int i,j;
Vec3b intensity;
intensity.val[0] = 0;
intensity.val[1] = 0;
intensity.val[2] = 0;
cv::Rect myROI(src.cols/6,0, 2*src.cols/3, src.rows);
Mat croppedImage = src(myROI);
Size size(300,600);
resize(croppedImage,src,size);//resize image
for(i = 0;i < src.rows;++i){
j = 0;
if((i < src.rows/25)||(i < (src.rows/25))){
for(j = 0;j < src.cols;++j){
src.at<Vec3b>(i,j)= intensity;
}
}
}
}
/** #function main */
int main( int argc, char ** argv )
{
loadImage("img/3h.png");
corpResizeImage();
detectImages();
/// Create Window
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, canny_output );
waitKey(0);
return(0);
}