I try to use the calcOpticalFlowSF() function, but when I launch it, the programm doesn't repond, here the part of the code that use it:
frame1 = cv::imread("frame10.png");
frame2 = cv::imread("frame11.png");
if (frame1.empty()) {
cout<<"could not read image oldori"<<endl;
return;
}
if (frame2.empty()) {
cout<<"could not read image ori"<<endl;
return;
}
if (frame1.rows != frame2.rows && frame1.cols != frame2.cols) {
cout<<"images should be of equal sizes "endl;
return;
}
if (frame1.type() != 16 || frame2.type() != 16) {
cout<<"images should be of equal type CV_8UC3")endl;
return;
}
cv::Mat flow;
cv::calcOpticalFlowSF(frame1, frame2, flow, 2, 2, 4);
// calcOpticalFlowSF(frame1, frame1, // doesn't work too.
// flow,
// 3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);
I know that the error come from the function calcOpticalFlowSF, because if I comment it, the programm works. I use the same pictures as they use in the SimpleFlow demo. If you look here:How to get cv::calcOpticalFlowSF to work? it seems that he got no problem with the function itself...
Do you have an idea why it doesn't work?
thanks,
best regards.
make sure the image is 3-channel, is better to see the docs here
#if 1
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include "opencv2/optflow.hpp"
#include "opencv2/highgui.hpp"
using namespace std;
using namespace cv;
using namespace cv::optflow;//calcOpticalFlowSF 's namespace
const size_t choice = 2 ;
// choice
// 1 2 3
// calcOpticalFlowFarneback calcOpticalFlowSF calcOpticalFlowPyrLK
void drawOptFlowMap(const Mat& flow, Mat& cflowmap, int step, const Scalar& color) {
// cflowmap is the pre frame with the line of Optical Flow
// flow is a xxx array, store float point
// store the delta of x,y
// step is every step pixel
for (int y = 0; y < cflowmap.rows; y += step)
for (int x = 0; x < cflowmap.cols; x += step)
{
const Point2f& fxy = flow.at< Point2f>(y, x);
line(cflowmap, Point(x, y), Point(cvRound(x + fxy.x), cvRound(y + fxy.y)),
color);
circle(cflowmap, Point(cvRound(x + fxy.x), cvRound(y + fxy.y)), 1, color, -1);
}
}
void drawOptFlowMap(Mat& cflowmap, int step, const Scalar& color, vector<Point2f> &retPts) {
// same as above, retPts is the next frame point
auto it = retPts.begin();
for (int y = 0; y < cflowmap.rows; y += step)
for (int x = 0; x < cflowmap.cols; x += step)
{
line(cflowmap, Point(x, y), *it, color);
circle(cflowmap, *it, 1, color, -1);
it++;
}
}
int main(int argc, char *argv[])
{
Mat flow;//flow = aft - pre
Mat pre = imread("1hf.png", IMREAD_COLOR);
Mat aft = imread("2hf.png", IMREAD_COLOR);// CV_LOAD_IMAGE_GRAYSCALE gray ; IMREAD_COLOR color
if (pre.empty() || aft.empty()){
printf("Unable to load the image");
return 1;
}
Mat cflow = pre; Mat cflow2 = aft;// store the 3-channel mat of frame, cflow is for show color with line
cvtColor(pre, pre, CV_BGR2GRAY);
cvtColor(aft, aft, CV_BGR2GRAY);
//below parameter of calcOpticalFlowPyrLK
vector<Point2f> prePts;
size_t step = 10;
vector<Point2f> nextPts(pre.rows * pre.cols);
vector<uchar> status;
vector<float> err;
TermCriteria termcrit(CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, 20, 0.03);
switch (choice)
{
case 1:// calcOpticalFlowFarneback
calcOpticalFlowFarneback(pre, aft, flow, 0.5, 3, 15, 3, 5, 1.2, 0); // info in the flow; note that input mat should in 1-channel
drawOptFlowMap(flow, cflow, 10, CV_RGB(0, 255, 0)); break;
case 2:// calcOpticalFlowSF
calcOpticalFlowSF(cflow, cflow2,
flow,
3, 2, 4, 4.1, 25.5, 18, 55.0, 25.5, 0.35, 18, 55.0, 25.5, 10);// info in the flow; note that input mat should in 3-channel
drawOptFlowMap(flow, cflow, 10, CV_RGB(0, 255, 0)); break;
case 3:// calcOpticalFlowPyrLK
for (int y = 0; y < pre.rows; y += step)
for (int x = 0; x < pre.cols; x += step)
{
prePts.push_back(Point(x, y));
}
// above get a point vector in step
calcOpticalFlowPyrLK(pre, aft, prePts, nextPts, status, err, Size(31, 31), 3, termcrit, 0, 0.001);// info in the flow; note that input mat should in 1-channel
drawOptFlowMap(cflow, step, CV_RGB(0, 255, 0), nextPts);
break;
default:
break;
}
imshow("pre", pre);
imshow("after", aft);
//cflow is the pre with OpticalFlow line
imshow("pre with OpticalFlow line", cflow);
waitKey(0);
return 0;
}
#endif
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 11 months ago.
Locked. There are disputes about this question’s content being resolved at this time. It is not currently accepting new answers or interactions.
I am new to c++, I started with it today and I got an error that I can't solve myself.
When I run my code it sometimes works fine, and I sometimes get an error after a few seconds.
The errors that I have gotten are:
"corrupted size vs. prev_size Aborted (core dumped)"
"segmentation fault (core dumped)"
This is my code:
#include <opencv2/opencv.hpp>
#include <iostream>
#include <random>
using namespace cv;
using namespace std;
using chrono::duration;
using chrono::duration_cast;
using chrono::high_resolution_clock;
using chrono::milliseconds;
class Product
{
public:
Point location = Point(-80, 0);
Scalar color;
Product(int given_y, Scalar given_color)
{
location.y = given_y;
color = given_color;
cout << "Product created" << endl;
}
Mat update(double speed, Mat img, double dt)
{
location.x += speed* dt;
circle(img, location, 25, Scalar(255, 255, 255), FILLED, LINE_8);
circle(img, location, 20, color, FILLED, LINE_8);
putText(img, "12", location + Point(-17, +7), FONT_HERSHEY_DUPLEX, .8, Scalar(255, 255, 255), 1, LINE_AA);
return (img);
}
};
int main(int argc, char **argv)
{
// Constant variables
const int kScreenWidth = 1920;
const int kScreenHeight = 1080;
const int kUpdateFpsMilliseconds = 600;
const String kWindowName = "Moving dots";
const Mat kBlackImg(kScreenHeight, kScreenWidth, CV_8UC3, Scalar(0, 0, 0));
// Variables
Scalar red = Scalar(255, 0, 0);
Scalar green = Scalar(0, 255, 0);
Scalar blue = Scalar(0, 0, 255);
Scalar cyan = Scalar(0, 255, 255);
Scalar magenta = Scalar(255, 0, 255);
Scalar yellow = Scalar(255, 255, 0);
Scalar black = Scalar(0, 0, 0);
Scalar white = Scalar(255, 255, 255);
vector<Product> products;
Mat img;
double speed = .2;
double fps;
int frame_counter = 0;
int loop_dt;
int time_since_fps_update = 0;
int counter = 0;
bool remove_product = false;
bool full_screen = false;
// Random number generators
random_device rd_seed;
mt19937 rng(rd_seed());
uniform_int_distribution<mt19937::result_type> rd_screen_height(50, kScreenHeight - 50);
uniform_int_distribution<mt19937::result_type> rd_new_product(0, 100);
namedWindow(kWindowName, WINDOW_NORMAL);
setWindowProperty(kWindowName, WND_PROP_FULLSCREEN, WINDOW_FULLSCREEN);
auto loop_start = high_resolution_clock::now();
while (true)
{
// Black image
Mat img = kBlackImg.clone();
// Add new products
if (rd_new_product(rng) < .1 * loop_dt)
{
products.push_back(Product(rd_screen_height(rng), red));
}
// Update products
if (products.size() > 0)
{
for (int i = 0; i <= products.size(); i++)
{
img = products[i].update(speed, img, loop_dt);
}
}
// Show text and border
stringstream temp;
temp << "FPS: " << fps << " Products: " << products.size();
putText(img, temp.str(), Point(18, 38), FONT_HERSHEY_DUPLEX, .8, white, 1, LINE_AA);
rectangle(img, Point(6, 6), Point(kScreenWidth - 6, kScreenHeight - 6), white, 12);
rectangle(img, Point(6, 6), Point(kScreenWidth - 6, 60 - 6), white, 12);
rectangle(img, Point(6, 6), Point(kScreenWidth - 6, kScreenHeight - 6), cyan, 3);
rectangle(img, Point(6, 6), Point(kScreenWidth - 6, 60 - 6), cyan, 3);
// Update screen
cvtColor(img, img, COLOR_RGB2BGR);
imshow(kWindowName, img);
// Exit script
if (waitKey(1) >= 0)
{
break;
};
// Handle FPS counter
frame_counter++;
loop_dt = duration_cast<milliseconds>(high_resolution_clock::now() - loop_start).count();
loop_start = high_resolution_clock::now();
time_since_fps_update += loop_dt;
if (time_since_fps_update > kUpdateFpsMilliseconds)
{
fps = (double)frame_counter / (double)time_since_fps_update * 1000;
time_since_fps_update -= kUpdateFpsMilliseconds;
frame_counter = 0;
}
}
destroyWindow(kWindowName);
return 0;
}
I think that it might have something to do with the color scalars or with the products vector.
Any help is appreciated!
The main culprit is likely:
for (int i = 0; i <= products.size(); i++)
{
img = products[i].update(speed, img, loop_dt);
}
That should be < products.size(). Vectors use indices from 0 to size()-1, like pretty much all other std containers.
For some background, I am compiling in Visual Studio 2019 and running the code inside LabVIEW 2017. The reason I am doing it in LabVIEW is for research to control a robotic gantry. This is the vision system and it is supposed to detect rectangles (wirebond pads for silicon detectors).
I need it to atleast show me a picture or something but when I run it in LabVIEW, it just says it is not responding and makes me hard close the program. So frustrating! If theres no huge errors in my C++ code then I know I have to dig deeper into my LabVIEW code.
The following code is my problem. I am fairly new to C++ and programming in general. I have done the step each line inside LabVIEW and when it stops responding is when it starts to grab the nominalHeight, xfov etc... or just when it goes into the WBPdetection function in general.
Any help is much appreciated. Or if someone could just point me in the right direction.
#include "stdafx.h"
#include "utils.h"
#include "WBPdetection.h"
#include "opencv2/opencv.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <vector>
using namespace std;
void show3(cv::Mat img)
{
cv::namedWindow("MyWindow", cv::WINDOW_AUTOSIZE);
cv::imshow("MyWindow", img);
cv::waitKey(0);
cv::destroyWindow("MyWindow");
}
__declspec(dllexport) int __cdecl WBPdetection(
char* imgPtr,
int imgLineWidth,
int imgWidth,
int imgHeight,
double percent_size,
double nominalWidth,
double nominalHeight,
double tolerance,
double xfov,
double yfov)
{
cv::Mat img(imgHeight, imgWidth, CV_8U, (void*)imgPtr, imgLineWidth);
cv::resize(img, img, cv::Size(img.cols * percent_size, img.rows * percent_size), 0, 0);
//PREPPING IMAGE FOR DETECTION ALGORITHIM
cv::threshold(img, img, 125, 255, cv::THRESH_OTSU);
cv::GaussianBlur(img, img, cv::Size(5, 5), 0);
cv::erode(img, img, cv::Mat(), cv::Point(-1, -1), 2, 1, 1);
cv::dilate(img, img, cv::Mat(), cv::Point(-1, -1), 1, 1, 1);
//USE FIND CONTOURS ALGORITHIM
vector<vector<cv::Point>> contours;
vector<cv::Vec4i> hierarchy;
cv::findContours(img, contours, hierarchy, cv::RETR_TREE, cv::CHAIN_APPROX_SIMPLE);
for( int i = 0; i < contours.size(); i++ )
{ approxPolyDP( cv::Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = cv::boundingRect( cv::Mat(contours_poly[i]) );
}
vector<vector<double>> dimRects; //ex [ [w1,h1], [w2,h2], [w3,h3], ...]
vector<cv::Point> centerRects; //ex [ [c1], [c2], [c3], ... ]
//PUTTING DIMENSIONS OF ALL RECTANGLES IN VECTORS
for (int i = 0; i < contours.size(); i++)
{
cv::Point center = ((boundRect[i].tl().x + boundRect[i].br().x) / 2, (boundRect[i].tl().y + boundRect[i].br().y) / 2); //what about even pixels
double rectWidth = (boundRect[i].br().x - boundRect[i].tl().x) * (xfov / img.cols); //might not matter tbh
double rectHeight = (boundRect[i].tl().y - boundRect[i].br().y) * (yfov / img.rows);
dimRects[i].push_back(rectWidth);
dimRects[i].push_back(rectHeight);
centerRects.push_back(center);
}
//DEFINING minWidth, etc... FROM tolerance AND nominalWidth
double minWidth = nominalWidth * (1 - tolerance);
double maxWidth = nominalWidth * (1 + tolerance);
double minHeight = nominalHeight * (1 - tolerance);
double maxHeight = nominalHeight * (1 + tolerance);
// DRAWING CONTOURS AND BOUNDING RECTANGLE + CENTER
for( int i = 0; i< dimRects.size(); i++ )
{
cv::Scalar color = cv::Scalar(255,255,255); //creates color
if ((dimRects[i][0] > minWidth && dimRects[i][0] < maxWidth) && (dimRects[i][1] > minHeight && dimRects[i][1] < maxHeight))
{
drawContours(img, contours_poly, i, color, 1, 8, vector<cv::Vec4i>(), 0, cv::Point());
rectangle(img, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0);
circle(img, centerRects[i], 1, cv::Scalar(0, 0, 255), 1, cv::LINE_8);
}
}
show3(img);
return 0;
}
Well there is one error here
vector<vector<double>> dimRects;
...
for (int i = 0; i < contours.size(); i++)
{
...
dimRects[i].push_back(rectWidth);
dimRects[i].push_back(rectHeight);
dimRects has zero size but your code treats it as if it has the same size as contours.
I am developing some video analytic algorithms using openCV. However, after I process a frame and want to display it on a window, it hangs at imshow() function. I have searched for this issue online but still cannot find the problem! Here is the code where I am using multithread and openCV:
void CFeatureExtraction::extract(){
boost::thread OpFlowThread, BGSThread;
while (m_nRun){
ImgPtr frame_ptr;
m_pQueue->wait_and_pop(frame_ptr);
Mat frame1, frame2;
(*frame_ptr).copyTo(frame1);
(*frame_ptr).copyTo(frame2);
OpFlowThread = boost::thread(&COpFlow::op_flow, m_pAlgo,frame1);
BGSThread = boost::thread(&CBGSub::bgsub, m_pBGS, frame2);
OpFlowThread.join();
BGSThread.join();
}
}
And inside op_flow and bgsub function, I am using imshow() and cvWaitKey() together! But it keeps hanging the whole program.
If my question is still not clear for you, pls feel free to ask me for more detail.
Here is the detail code of calling imshow():
CFarnebackAlgo::CFarnebackAlgo() : COpFlow()
{
namedWindow("Optical Flow");
}
CFarnebackAlgo::~CFarnebackAlgo()
{
destroyWindow("Optical Flow");
}
int CFarnebackAlgo::op_flow(Mat frame)
{
Mat flow;
cvtColor(frame, gray, COLOR_BGR2GRAY);
if (prevgray.data)
{
calcOpticalFlowFarneback(prevgray, gray, flow, 0.5, 3, 15, 3, 5, 1.2, 0);
for (int y = 0; y < frame.rows; y += 8)
for (int x = 0; x < frame.cols; x += 8){
const Point2f& fxy = flow.at<Point2f>(y, x);
line(frame, Point(x, y), Point(cvRound(x + fxy.x), cvRound(y + fxy.y)), Scalar(0, 255, 0));
circle(frame, Point(x, y), 2, Scalar(0, 255, 0), -1);
}
if (frame.data == NULL){
cout << "No Img!" << endl;
exit(0);
}
imshow("Optical Flow", frame);
waitKey(50);
}
std::swap(prevgray, gray);
return 0;
}
If I put the namedWindow() in the op_flow(), it is working. But if I put it in the constructor, it's not working and freezes. Anyone knows why?
I am trying to find the optical flow between two sequence of images,when I run the program it shows up assertion failed at calcOpticalFlowFarneback() function.Can anyone help me with this issue.
#include "stdafx.h"
#include<opencv\cv.h>
#include<opencv2\highgui\highgui.hpp>
#include<opencv2\calib3d\calib3d.hpp>
#include<opencv2\core\core.hpp>
using namespace cv;
using namespace std;
void drawOptFlowMap (const Mat& flow, Mat& cflowmap, int step, double scale, const
Scalar& color)
{
for(int y = 0; y < cflowmap.rows; y += step)
for(int x = 0; x < cflowmap.cols; x += step)
{
const Point2f& fxy = flow.at<Point2f>(y, x);
line(cflowmap, Point(x,y), Point(cvRound(x+fxy.x), cvRound(y+fxy.y)),
color);
circle(cflowmap, Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), 1, color, -1);
}
}
int main()
{
Mat flow,cflow;
Mat Previous_Gray=imread("image2.png");
Mat Current_Gray=imread("image3.png");
cvtColor(Current_Gray,Current_Gray,CV_BGR2GRAY);
cvNamedWindow("optical Flow", CV_WINDOW_NORMAL);
calcOpticalFlowFarneback(Previous_Gray,Current_Gray,flow,0.5, 3, 15, 3, 5, 1.2, 0);
cvtColor(Previous_Gray, cflow, CV_GRAY2BGR);
drawOptFlowMap(flow, cflow, 32, 50, CV_RGB(0, 255, 0));
imshow("optical Flow", cflow);
return 0;
}
Mat imread(const string& filename, int flags=1), what is the call you're using in the line Mat Previous_Gray=imread("image2.png"); returns an 3 channel rgb image. So beacuse part of the assertion
prev0.channels() == next0.channels() == 1
is false. Did you forget to convert PreviousGray before call calcOpticalFlowFarneback?
http://docs.opencv.org/modules/highgui/doc/reading_and_writing_images_and_video.html#imread
I've read the documentation for calcHist() many times, but I think my inexperience with OpenCV and rusty programming skills are completely precluding me from understanding it.
I'm looking to count pixels in one channel of an HSV image (Hue, or channel[0]) for segmentation purposes using 10 bins that closely approximate color according to something like (let's use this as an example, I stole the ranges off the web - fwiw, it seems erroneous to omit purple-red):
Red: 0-19 & 330-360
Red-Yellow (RY): 20-49
Yellow: 50-69
YG: 70-84
Green: 85-170
GB: 171-191
Blue: 192-264
BP: 265-289
Purple: 290-329
And so on...
So how do I do this with calcHist?
I'm as far as:
#include <opencv2/opencv.hpp>
#include <vector>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char *argv[])
{
Mat scene, sceneHSV, dest, histo;
int numImages = 1, histChannel[] = {0}, dims = 1, histSize[] = {10};
float redRange[] = {0, 10};
float roRange[] = {10, 25};
float orangeRange[] = {25, 35};
float oyRange[] = {35, 42};
float yellowRange[] = {42, 85};
float ygRange[] = {85, 96};
float greenRange[] = {96, 132};
float gbRange[] = {132, 145};
float blueRange[] = {145, 160};
float bpRange[] = {160, 165};
float purpleRange[] = {165, 180};
const float* ranges[] = {redRange, roRange, orangeRange, oyRange, yellowRange, ygRange, greenRange, gbRange, blueRange, bpRange, purpleRange};
vector<Mat> channels;
scene = imread("Apple.jpg", 1);
if (scene.data == NULL)
{
cout<<"FAIL"<<endl;
cin.get();
}
cvtColor(scene, sceneHSV, CV_BGR2HSV);
dilate(sceneHSV, sceneHSV, Mat(), Point(-1, -1), 1, BORDER_CONSTANT, 1);
pyrMeanShiftFiltering(sceneHSV, dest, 2, 50, 3);
split(sceneHSV, channels);
calcHist(&scene, 1, histChannel, Mat(), histo, dims, histSize, ranges, false, false);
cout<<histo<<endl;
waitKey(0);
return 0;
}
Now what? What would the arguments to calcHist look like in this case, and what does the output histogram look like? Simply a 1x9 array full of ints?
Thanks very much.
I modified the code from here
You might also want to take a look at the documentation of cvtColor here
Note that I have not tried to compile or run this code so I do not guarantee that it will work. But nonetheless, it might be useful as a reference.
Mat hist;
int nimages = 1; // Only 1 image, that is the Mat scene.
int channels[] = {0} // Index for hue channel
int dims = 1 // Only 1 channel, the hue channel
int histSize[] = {9} // 9 bins, 1 each for Red, RY, Yellow, YG etc.
float hranges[] = { 0, 180 }; // hue varies from 0 to 179, see cvtColor
const float *ranges[] = {hranges};
// Compute the histogram.
calcHist(&scene,
nimages,
channels,
Mat(), // No mask
hist, dims, histSize, ranges, uniform=true)
// Now hist will contain the counts in each bin.
// Lets just print out the values. Note that you can output Mat using std::cout
cout << "Histogram: " << endl << hist << endl;
// To access the individual bins, you can either iterate over them
// or use hist.at<uchar>(i, j); Note that one of the index should be 0
// because hist is 1D histogram. Print out hist.rows and hist.cols to see if hist is a N x 1 or 1 x N matrix.
/*
MatIterator_<uchar> it, end;
int binIndex = 0;
for( it = hist.begin<uchar>(), end = hist.end<uchar>(); it != end; ++it)
{
printf("Count in %d bin: %d\n", binIndex, *it);
++binIndex;
}
*/