using cvRetrieveFrame get strange image - opencv

I am reading a avi file, and do some background subtrcation work. The wierd thing is when I use cvRetrieveFrame, I got a strange image, like below:
origin:
cvRetrieveFrame returns:
I don't know what's the problem. Here is my code snippet.
CvCapture* readerAvi = cvCaptureFromAVI( filename.c_str() );
if(readerAvi == NULL)
{
std::cerr << "Could not open AVI file." << std::endl;
return 0;
}
// retrieve information about AVI file
cvQueryFrame(readerAvi); //....get some information, width, height, ....
// grad next frame from input video stream
if(!cvGrabFrame(readerAvi))
{
std::cerr << "Could not grab AVI frame." << std::endl;
return 0;
}
frame_data = cvRetrieveFrame(readerAvi);

Related

Azure Kinect Recording Color Format

I'm attempting to read an Azure Kinect recording and save images from the frames. But, it is not possible to set the color_format, which causes problems when using imwrite.
I have read the recording documentation here: https://learn.microsoft.com/en-us/azure/Kinect-dk/azure-kinect-recorder.
By default, the format seems to be K4A_IMAGE_FORMAT_COLOR_MJPG. But I am unsure what parameter to pass in when creating the material. For BGRA32 it is CV_8UC4 and for depth images it is CV_16U.
I assume there are two ways to solve this problem, either by setting the color_format or figuring out what parameter is correct for the default format made by the recording.
You can access the rgb with OpenCV as if it were a normal webcam:
VideoCapture cap(0); // open the default camera
cap.set(CV_CAP_PROP_FRAME_WIDTH, 3840);
cap.set(CV_CAP_PROP_FRAME_HEIGHT, 2160);
if (!cap.isOpened()) // check if we succeeded
return -1;
Mat frame, img;
for (;;)
{
cap >> frame; // get a new frame from camera
cout << frame.cols << " x " << frame.rows << endl;
resize(frame, img, Size(), 0.25, 0.25);
imshow("frame", img);
if (waitKey(30) >= 0) break;
}
No k4a function is called, no need to set the color format.
If you want to use their SDK with jpeg format, they provide a function in one of their sample codes:
long WriteToFile(const char *fileName, void *buffer, size_t bufferSize)
{
cout << bufferSize << endl;
assert(buffer != NULL);
std::ofstream hFile;
hFile.open(fileName, std::ios::out | std::ios::trunc | std::ios::binary);
if (hFile.is_open())
{
hFile.write((char *)buffer, static_cast<std::streamsize>(bufferSize));
hFile.close();
}
std::cout << "[Streaming Service] Color frame is stored in " << fileName << std::endl;
return 0;
}
You just call:
image = k4a_capture_get_color_image(capture);
WriteToFile("color.jpg", k4a_image_get_buffer(image), k4a_image_get_size(image));
Finally, you can set the format to RGBA32:
config.color_format = K4A_IMAGE_FORMAT_COLOR_BGRA32;
and convert it into a OpenCV Mat:
color_image = k4a_capture_get_color_image(capture);
if (color_image)
{
uint8_t* buffer = k4a_image_get_buffer(color_image); // get raw buffer
cv::Mat colorMat(Hrgb, Wrgb, CV_8UC4, (void*)buffer, cv::Mat::AUTO_STEP);
//do something with colorMat
k4a_image_release(color_image);
}
More details on the last option here: How to convert k4a_image_t to opencv matrix? (Azure Kinect Sensor SDK)
The data is slightly better with the last solution, but the buffer is significantly larger (33M vs ~1.5M) for 3840x2160.

Getting Assertion (-215) error while using the opencv stitcher class in vs

So many type of questions like this has been asked, and i have pass through most of them but cant still get a solution to my problem, this is the error code though: error (-215:Assertion failed) size.width>0 && size.height>0 in function 'cv::imshow'
bool try_use_gpu = false;
vector<Mat>imgs;
Mat image, pano;
image = imread("moscow1.jpg");
if (image.empty())
{
cout << "check your input image" << endl;
return EXIT_FAILURE;
}
imgs.push_back(imread("moscow1.jpg"));
image = imread("moscow2.jpg");
if (image.empty())
{
cout << "check your input image" << endl;
return EXIT_FAILURE;
}
imgs.push_back(imread("moscow2.jpg"));
Stitcher::Mode mode = Stitcher::PANORAMA;
Ptr<Stitcher> stitcher = Stitcher::create(mode, try_use_gpu);
//Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
Stitcher::Status status = stitcher->stitch(imgs, pano);
if (status != Stitcher::OK)
{
cout << "Panorama unsuccessful" << endl;
}
imshow("panorama", pano);
waitKey(0);
imwrite("panoramaimg.jpg", pano);
}
am also thinking if am not implementing the stitcher class well, any help will do...
The images you want to stitch must have common point, for the program to use, use two different images is just not going to work if the images have no common point..

Detect frame drop in OpenCV

How can I detect a dropped frame in OpenCV? Right now I am doing a check like the following:
int main() {
VideoCapture cap(-1);
if (!cap.isOpened()) {
cout << "Webcam is not open." << endl;
return -1;
}
Mat frame;
while (true) {
cap.read(frame);
if (!frame.empty()) {
imshow("frame", frame);
}
else {
cout << "No captured frame" << endl;
break;
}
}
}
But I still get messages saying "Camera frame dropped!" without my "No captured frame" message. What conditions result in the camera frame being dropped/how can I check for those conditions?
You can use this opencv function cap.get(CV_CAP_PROP_POS_MSEC) to obtain the presentation timestamp of a videoframe. This function returns an integer in multiples of time interval. If any frame drop, the timestamp would have skipped to (N+2)*time_interval instead of (N+1)*time_interval where N is your current frame number.

OpenCV FileStorage empty after loading

Im trying to load a string into filestorage. I will not have the file to pass filename as a parameter to load it. Instead I recive an xml document as a string. In the doc http://docs.opencv.org/modules/core/doc/xml_yaml_persistence.html#filestorage it is mentioned that source attribute of fs.open can be "text string to read the data from". I run some simple tests with OpenCv CascadeClassifier as a string but I get an empty FileStorage. What am I doing wrong?
CascadeClassifier face_cascade;
std::ifstream t("haarcascade_frontalface_alt.xml");
std::string ClasifierInString((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
cout << ClasifierInString << endl; //I CAN PRINT THE FILE AND SEE IT
cv::FileStorage fs;
if (!fs.open(ClasifierInString, cv::FileStorage::READ | cv::FileStorage::MEMORY | cv::FileStorage::FORMAT_XML))
{
cout << "Couldn't load file into memory" << endl;
return -2;
}
FileNodeIterator it = fs.getFirstTopLevelNode().begin(), it_end = fs.getFirstTopLevelNode().end();
for (; it != it_end; ++it)
{
cout << (string)*it << "\n"; //EMPTY LINE????
}
if (!face_cascade.read(fs.getFirstTopLevelNode()))
{
cout << "Couldn't read file from memory" << endl;
return -1;
}
EDIT:
#sop can't comment yet. Maybe your using older version of OpenCV. I have the file and I am able to load it with:
face_cascade.load("haarcascade_frontalface_alt.xml");
and it works. The problem is I'm unable to read it as a string with face_cascade.read(string)
#berak comment is the correct answer. I used lbpcascade_frontalface.xml as this is new cascade (and is faster! :) Thx for help.
I think your problem is the file name: "haarcascade_frontalface_alt.xml". There is no such a file in the OpenCV flder... Try "haarcascade_frontalface_alt_tree.xml".
Here is my code that works:
cv::CascadeClassifier face_cascade;
std::ifstream t("haarcascade_frontalface_alt_tree.xml");
std::string ClasifierInString((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
std::cout << ClasifierInString << std::endl; //I CAN PRINT THE FILE AND SEE IT
cv::FileStorage fs;
if (!fs.open(ClasifierInString, /*cv::FileStorage::READ | */cv::FileStorage::MEMORY | cv::FileStorage::FORMAT_XML))
{
std::cout << "Couldn't load file into memory" << std::endl;
return -2;
}
cv::FileNodeIterator it = fs.getFirstTopLevelNode().begin(), it_end = fs.getFirstTopLevelNode().end();
for (; it != it_end; ++it)
{
std::cout << (std::string)*it << "\n"; //EMPTY LINE????
}
if (!face_cascade.read(fs.getFirstTopLevelNode()))
{
std::cout << "Couldn't read file from memory" << std::endl;
return -1;
}

ip camera foscam jpeg streaming in opencv, only reads first frame from video

I am using opencv 2.4.7, windows 7 and vc++2010 to stream mjpeg from a foscam ip camera. cap.isOpened is not null but only the first frame is displayed and breaks from loop in the second round. this is part of the code I am using:
VideoCapture cap("http://IP:PORT/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=X&pwd=Y&.mjpg"); // open the video file for reading
if ( !cap.isOpened() ) // if not success, exit program
{
std::cout << "Cannot open the video file" << std::endl;
return -1;
}
cap.set(CV_CAP_PROP_POS_MSEC, 30); //start the video at 300ms
double fps = cap.get(CV_CAP_PROP_FPS); //get the frames per seconds of the video
std::cout << "Frame per seconds : " << fps << std::endl;
namedWindow("MyVideo",CV_WINDOW_AUTOSIZE); //create a window called "MyVideo"
int cnt=0;
Mat frame;
for(;;)
{
bool bSuccess = cap.read(frame); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
std::cout << "Cannot read the frame from video file" << std::endl;
break;
}
imshow("MyVideo", frame); //show the frame in "MyVideo" window
if(waitKey(33) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
std::cout << "esc key is pressed by user" << std::endl;
break;
}
}
}
I appreciate any help in advance.
look at your url:
"IP:PORT/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=X&pwd=Y&.mjpg"
snapPicture2 looks suspicious, no ?
i'm pretty sure, there's no problem with your opencv code,
it's more like the url you choose only retrieves 1 frame
please lookup your manual for the correct stream url
http://www.ispyconnect.com/man.aspx?n=foscam

Resources