We can easily use opencv to open the camera to capture videos.
# Include <opencv2/highgui. HPP> # include <opencv2/imgproc. HPP> # include <opencv2/CORE/core. HPP> using namespace CV; int main () {videocapture cap (0); If (! Cap. isopened () {return-1;} mat frame; MAT edges; bool stop = false; while (! Stop) {cap> frame; // cvtcolor (frame, edges, cv_bgr2gray); // gaussianblur (edges, edges, size (7, 7), 1.5, 1.5 ); // canny (edges, edges, 0, 30, 3); imshow ("current video", frame); If (waitkey (30)> = 0) Stop = true ;} return 0 ;}
The videocapture class has two usage methods: videocapture (const string & filename) is used to open a video file, and videocapture (INT device) is used to open a device.
Select an appropriate parameter based on your needs. The comment part is that if you want an edge image, you can use it like this and use it to solve the problem by using the "quick" command.
Opencv provides many functions for video processing, such as the number of frames and FPS of videos that we care about.
# Include <opencv2/highgui. HPP> # include <opencv2/imgproc. HPP> # include <opencv2/CORE/core. HPP> # include <iostream> using namespace STD; using namespace CV; int main () {// open the video file: in fact, it is to create a videocapture structure videocapture capture ("/usr/share/example-content/ubuntu_free_culture_showcase/How fast.ogg"); // check whether it is enabled properly: when it is enabled successfully, isopened returns true if (! Capture. isopened () cout <"fail to open! "<Endl; // get the total number of frames long totalframenumber = capture. get (cv_cap_prop_frame_count); cout <"total video" <totalframenumber <"frame" <Endl; // set the start frame () Long frametostart = 300; capture. set (cv_cap_prop_pos_frames, frametostart); cout <"starting from" <frametostart <"starting from frame read" <Endl; // sets the end frame int frametostop = 400; if (frametostop <frametostart) {cout <"the end frame is smaller than the start frame. The program is incorrect and will exit soon! "<Endl; Return-1 ;}else {cout <" end frame: "<frametostop <" frame "<Endl ;} // obtain the frame rate double rate = capture. get (cv_cap_prop_fps); cout <"Frame Rate:" <rate <Endl; // defines a variable bool stop = false to control the end of the read Video loop; // The Mat frame of the image that carries each frame; // display the namedwindow ("extracted frame") of each frame; // The interval between the two frames: // int delay = 1000/rate; int delay = 1000/rate; // using the while loop to read frames // currentframe is the variable long currentframe = frametostart after the specified frame is read in the loop body; // The Int kernel_size of the filter core = 3; MAT kernel = mat: ones (kernel_size, kernel_size, cv_32f)/(float) (kernel_size * kernel_size); While (! Stop) {// read the next frame if (! Capture. read (FRAME) {cout <"failed to read Video" <Endl; Return-1 ;}// Add the filter program // imshow ("extracted frame ", frame); // filter2d (frame, frame,-1, kernel); imshow ("after filter", frame ); cout <"reading the nth" <currentframe <"frame" <Endl; // waitkey (INT delay = 0) will always wait when delay ≤ 0; when delay is greater than 0, it will wait for delay in milliseconds // when no key is pressed before the end of the time, the returned value is-1; otherwise, the Return key is int c = waitkey (Delay ); // Press ESC or exit to read the video if (char) C = 27 | currentframe> frametostop) {stop = true ;} // press the button and it will stay in the current frame. Wait for the next button if (C> = 0) {waitkey (0) ;}currentframe ++ ;} // disable the video file capture. release (); waitkey (0); Return 0 ;}
If your video encounters any problems, you can use the filter to smooth it.
I read a lot of other people's blog posts and books. I don't know much about LUT and histogram balancing.
Here, let's look at other people's blog posts and look at http://blog.csdn.net/thefutureisour/article/details/7532765.
First, create a class:
[CPP]
View plaincopy
- Class histogram1d
- {
- PRIVATE:
- // Number of points in the Histogram
- Int histsize [1];
- // Histogram range
- Float hranges [2];
- // Pointer to this range
- Const float * ranges [1];
- // Channel
- Int channels [1];
- Public:
- // Constructor
- Histogram1d ()
- {
- Histsize [0] = 256;
- Hranges [0] = 0.0;
- Hranges [1] = 255.0;
- Ranges [0] = hranges;
- Channels [0] = 0;
- }
In opencv, use calchist to calculate the Histogram
[CPP]
View plaincopy
- Mat gethistogram (const mat & image)
- {
- Mat hist;
- // Calculate the histogram Function
- // Parameter: source image (sequence) address, number of input images, number of channels, mask, output result, histogram dimension, size of each dimension, value range of each dimension
- Calchist (& image, 1, channels, MAT (), Hist, 1, histsize, ranges );
- Return hist;
- }
However, the returned result is not the desired "histogram". hist only records the number of pixels in each bin. We need to use the line function to draw pictures by ourselves:
[CPP]
View plaincopy
- Mat gethistogramimage (const mat & image)
- {
- // Calculate the histogram first
- Mat hist = gethistogram (image );
- // Obtain the maximum and minimum values
- Double maxval = 0;
- Double minval = 0;
- // Minmaxloc is used to obtain the maximum and minimum values. The following two parameters are the minimum and maximum values. 0 indicates that no value is required.
- Minmaxloc (Hist, & minval, & maxval, 0, 0 );
- // Display the canvas of the histogram. The background color is white.
- Mat histimg (histsize [0], histsize [0], cv_8u, scalar (255 ));
- // Set the highest point to 90% of the total bin count
- Int hpt = static_cast <int> (0.9 * histsize [0]);
- // Draw a line for each Bin
- For (INT h = 0; H
- {
- Float binval = Hist. at <float> (h );
- Int intensity = static_cast <int> (binval * HPT/maxval );
- // Int intensity = static_cast <int> (binval );
- Line (histimg, point (H, histsize [0]), point (H, histsize [0]-intensity), scalar: All (0 ));
- }
- Return histimg;
- }
The function compresses the brightness to better display the histogram on the canvas.
A look-up table is a one-to-one or multiple-to-one function that specifies a brightness that is converted into another pixel after the look-up table. Using the LUT function in opencv
[CPP]
View plaincopy
- Mat applylookup (const mat & image, const mat & lookup)
- {
- Mat result;
- LUT (image, lookup, result );
- Return result;
- }
The specific content of the change depends on the search table defined by you. For example, if you want the search table to result in the flip of the current image, you can define the search table in the main function:
[CPP]
View plaincopy
- // Use the lookup table to flip the image grayscale
- Int dim (256 );
- Mat LUT (1, & dim, cv_8u );
- For (INT I = 0; I <256; I ++)
- {
- LUT. at <uchar> (I) = 255-i;
- }
- Imshow ("images after gray scale flip", H. applylookup (image, LUT ));
When you want to make the histogram stretch after the image goes through the search table, the effect will be better:
Remove the bin with a number lower than the specified number (0 by default). The remaining minimum value is 0, the maximum value is 255, and the linear stretching of the middle part is as follows:
[CPP]
View plaincopy
- Mat strech (const mat & image, int minvalue = 0)
- {
- // Calculate the histogram first
- Mat hist = gethistogram (image );
- // Left entry
- Int Imin = 0;
- For (; Imin
- {
- Cout <Hist. at <float> (Imin) <Endl;
- If (Hist. at <float> (Imin)> minvalue)
- Break;
- }
- // Right entry
- Int IMAX = histsize [0]-1;
- For (; IMAX> = 0; IMAX --)
- {
- If (Hist. at <float> (IMAX)> minvalue)
- Break;
- }
- // Create a search table
- Int dim (256 );
- Mat Lookup (1, & dim, cv_8u );
- For (INT I = 0; I <256; I ++)
- {
- If (I <Imin)
- {
- Lookup. at <uchar> (I) = 0;
- }
- Else if (I> IMAX)
- {
- Lookup. at <uchar> (I) = 255;
- }
- Else
- {
- Lookup. at <uchar> (I) = static_cast <uchar> (255.0 * (I-Imin)/(IMAX-Imin) + 0.5 );
- }
- }
- Mat result;
- Result = applylookup (image, lookup );
- Return result;
- }
Of course, this effect is not the best. The best balancing should make the histogram very gentle, and the number of each bin is similar. In opencv, you can use the equalizehist function to implement the histogram balancing function:
[CPP]
View plaincopy
- Mat equalize (const mat & image)
- {
- Mat result;
- Equalizehist (image, result );
- Return result;
- }
With the class defined above, the main function becomes much simpler:
[CPP]
View plaincopy
- # Include "histogram. H"
- Int main ()
- {
- // Read the image in grayscale Mode
- Mat image = imread ("D:/picture/images/group.jpg", 0 );
- Imshow ("Source grayscale image", image );
- If (! Image. Data)
- Return-1;
- Histogram1d h;
- Imshow ("histogram", H. gethistogramimage (image ));
- // Use the lookup table to flip the image grayscale
- Int dim (256 );
- Mat LUT (1, & dim, cv_8u );
- For (INT I = 0; I <256; I ++)
- {
- LUT. at <uchar> (I) = 255-i;
- }
- Imshow ("images after gray scale flip", H. applylookup (image, LUT ));
- // Use the lookup table to stretch the gray value of the image
- // Ignore the bins with less than 100 pixels
- Mat strech = H. strech (image, 100 );
- Imshow ("stretched image", strech );
- Imshow ("stretched histogram", H. gethistogramimage (strech ));
- // Image balancing
- Mat afterequalize = H. equalize (image );
- Imshow ("solution after balancing", afterequalize );
- Imshow ("histogram after balancing", H. gethistogramimage (afterequalize ));
- Waitkey (0 );
- Return 0;
- }