Gra*_*ver 2 c++ opencv image-processing
我用OpenCV库用c ++编写了一个程序.该程序记录来自网络摄像头的视频,然后将其分成帧.我想知道帧是否在RGB中,因为我想访问每个像素的RGB属性.捕获的编解码器是CV_FOURCC('M','J','P','G').如何在RGB色彩空间中获取帧?
int main() {
Mat image;
VideoCapture cap(0);
cap.set(CV_CAP_PROP_FPS, 10);
if ( !cap.isOpened() ) {
cout << "ERROR : Cannot open the video file"<<endl;
return -1;
}
namedWindow("MyWindow", CV_WINDOW_AUTOSIZE);
double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH);
double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
cout << "Frame size :" << dWidth << "x" << dHeight << endl;
Size frameSize(static_cast<int>(dWidth), static_cast<int>(dHeight));
VideoWriter oVideoWriter("E:/myVideo.avi", CV_FOURCC('M', 'J', 'P', 'G'), 10, frameSize, true);
if (!oVideoWriter.isOpened()) {
cout << "ERROR : Failed to write the video"<<endl;
return - 1;
}
while (1) {
Mat image;
bool bSuccess = cap.read(image);
if (!bSuccess) {
cout << "ERROR : Cannot read a frame from video file" << endl;
break;
}
oVideoWriter.write(image);
imshow("MyWindow", image);
if (waitKey(10) == 27) {
saveImages();
cout << "ESC key is pressed by user" << endl;
break
}
}
return 0;
}
int saveImages() {
CvCapture *capture = cvCaptureFromFile("E:/myVideo.avi");
if(!capture)
{
cout<<"!!! cvCaptureFromAVI failed (file not found?)"<<endl;
return -1;
}
int fps = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
IplImage* frame = NULL;
int frame_number = 0;
char key = 0;
while (key != 'q')
{
frame = cvQueryFrame(capture);
if (!frame)
{
cout<<"!!! cvQueryFrame failed: no frame"<<endl;
break;
}
char filename[100];
strcpy(filename, "frame_");
char frame_id[30];
_itoa(frame_number, frame_id, 10);
strcat(filename, frame_id);
strcat(filename, ".jpg");
printf("* Saving: %s\n", filename);
if (!cvSaveImage(filename, frame))
{
cout<<"!!! cvSaveImage failed"<<endl;
break;
}
frame_number++;
key = cvWaitKey(1000 / fps);
}
cvReleaseCapture(&capture);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
当OpenCV从磁盘,摄像机或视频文件加载彩色图像(即3通道)时,图像数据将以BGR格式存储.这是一个简单的测试,你可以做:
/* Code using the C++ API */
cv::VideoCapture cap(0);
if (!cap.isOpened()) {
std::cout << "!!! Failed to open webcam" << std::endl;
return -1;
}
if (!cap.read(frame)) {
std::cout << "!!! Failed to read a frame from the camera" << std::endl;
return -1;
}
bool is_colored = false;
if (frame.channels() == 3) {
is_colored = true;
}
// Do something with is_colored
// ...
Run Code Online (Sandbox Code Playgroud)
除非你有一个奇怪的相机,框架将始终着色(因此,存储为BGR).
当cv::imwrite()调用(C++ API)或cvSaveImage()(C API)时,OpenCV会采用适当的魔术技巧来确保数据以与请求的输出格式(JPG,PNG,AVI等)兼容的方式保存,并且在此过程中它会自动转换如果需要,数据到RGB.
然而,如果由于某种原因你需要将图像转换为RGB,你可以调用:
cv::Mat img_rgb;
cv::cvtColor(frame, img_rgb, CV_BGR2RGB);
Run Code Online (Sandbox Code Playgroud)
请注意,OpenCV有一个C API和一个C++ API,它们不应混合使用:
如果您使用,IplImage那么坚持使用其余的C API.
如果您决定使用cv::Mat,请继续使用C++ API.
有不同的方法来访问a的像素cv::Mat,这里有一个:
unsigned char* pixels = (unsigned char*)(frame.data);
for (int i = 0; i < frame.rows; i++)
{
for (int j = 0; j < frame.cols; j++)
{
char b = pixels[frame.step * j + i] ;
char g = pixels[frame.step * j + i + 1];
char r = pixels[frame.step * j + i + 2];
}
}
Run Code Online (Sandbox Code Playgroud)