Detection of Black Pixels in Video
Hi everyone!
I still have problems with the property FPS, because I can't get it autocatically.
[avi @ 0x8e14540] time base not set
Could not open the output video for write: /home/margarida/Output.avi
Additionally, my goal is only to find colour frames, i.e. I need to remove all the frames constituted with black pixels from my input videos. And I get the error:
Segmentation fault (core dumped)
Does anyone detects any error? Or as a solution for my problems? Thanks in advance.
My code is:
int main(int argc, char* argv[]) {
VideoCapture cap;
VideoWriter outputVideo;
string name;
Mat frame;
int j;
for (j = 1; j < argc; j++) {
printf("%d: %s\n", j, argv[j]);
string str1 = argv[j];
unsigned found = str1.find_last_of("/");
name = str1.substr(0, found);
string newname = name + "/Output.avi";
cout << newname << '\n';
cap.open(argv[j]);
if (!cap.isOpened()) {
cout << "Could not open the input video: " << argv[j] << endl;
return -1;
}
//codec type
int ex = CV_FOURCC('X', 'V', 'I', 'D');
//transform from int to char via Bitwise operators
char EXT[] = { (char) (ex & 0XFF), (char) ((ex & 0XFF00) >> 8),
(char) ((ex & 0XFF0000) >> 16),
(char) ((ex & 0XFF000000) >> 24), 0 };
cout << "Input Codec: " << EXT << endl;
//acquire input size
Size S = Size((int) cap.get(CV_CAP_PROP_FRAME_WIDTH),
(int) cap.get(CV_CAP_PROP_FRAME_HEIGHT));
//get fps
//double fps = cap.get(CV_CAP_PROP_FPS);
// Open the output
//outputVideo.open(newname, ex, fps, S, true);
outputVideo.open(newname, ex, 13, S, true);
if (!outputVideo.isOpened()) {
cout << "Could not open the output video for write: " << newname
<< endl;
return -1;
}
while (true) {
cap >> frame;
if (frame.empty()) {
cerr << "didnt catch frame" << endl;
break;
}
for (int i = 0; i < frame.cols; i++) {
for (int j = 0; j < frame.rows; j++) {
//if all the pixels != 0 [black] - clone frame
if ((frame.at < Vec3b > (i, j).val[0] != 0)
&& (frame.at < Vec3b > (i, j).val[1] != 0)
&& (frame.at < Vec3b > (i, j).val[2] != 0)) {
Mat frame1 = frame.clone();
imshow("Output", frame1);
out.write(frame1);
}
}
}
}
return 0;
}
Like being said before, the
cap.get(CV_CAP_PROP_FPS)
will only work if the capture interface behind it has a proper covering of that function and if your camera supports grabbing the value through its interface. If not, than this will become impossible. You could simple run a first time over your video, reading in the frames by pointer and perform the FPS calculation yourself.So do something like total frames / total time of my video? And then do the rest?
Yeah simple loop like this
Thanks :) I finally realized what you already tried to tell me. Any suggestion on the other thing?
Basically for each frame you will have to count how many pixels differ from black. If that value is larger than 0 then you keep the frame, else you remove it.
just an optimization hint, you can replace the checking pixels value loop with just calling the countnonzero() function.
But my frames have 3 channels. So I'll need to call the countnonzero() function for every channel?
I tried to set a timer. Like http://stackoverflow.com/questions/22148826/measure-opencv-fps but it doesn't return a correct fps.
yup you either call countnonzero() for each channel or you can combine it with the inRange() (i.e. threshold the black color) function, create a mask and then call the countnonzero() on the mask.
Is something like this correct?
Using the mask and the function inRange() it doesn't return anything.
And using my solution even when the frame is black, it's cloned.