gpt4 book ai didi

c++ - 使用 OpenCV 2.4.3 的双线性插值的 VideoCapture 旋转

转载 作者:太空宇宙 更新时间:2023-11-03 23:02:18 24 4
gpt4 key购买 nike

我正在使用双线性插值实现视频捕捉旋转,就像 OpenCV 库中的 warpAffine() 一样。但到目前为止我遇到了一些问题:

1.我在轮换期间得到了一些伪像。以下是边框、90 度旋转和 360 度伪像的示例

https://www.dropbox.com/sh/oe51ty0cy695i3o/hcAzwmAk6z

enter image description here

enter image description here

enter image description here

2.我无法使用

更改捕获的分辨率
capture.set(CV_CAP_PROP_FRAME_WIDTH, 1280 )
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 720 )

两者都返回假值。

我使用 LifeCam Cinema。

这是我的代码:

#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <cmath>
#include <ctime>

#include <iostream>
#include <cstdlib>

using namespace cv;
using namespace std;

const double M_PI = 3.14159265359;

void print_help( const char* prg );
Mat rotate( Mat& in, int angle , Point2f rotationCenter );

inline uchar int2uchar( int color ) {
return (uchar)( color < 0 ? 0 : color > 255 ? 255 : color );
}

void print_help( const char* prg ) {
cout << "Report:" << endl;
cout << "Application : " << prg << endl;
cout << "Can't access capture device" << endl;
}

// rotation with bilinear interpolation
Mat rotate( Mat& in, int angle , Point2f rotationCenter ) {

// Note : added Scalar(0) for unused pixels to be black
Mat out( in.size(), in.type(), Scalar(0) );

float in_radians = (float)( angle * M_PI / 180 );
float sinAngle = (float)( sin( in_radians ) );
float cosAngle = (float)( cos( in_radians ) );

for ( int col(0); col < in.cols; ++col ) {
for ( int row(0); row < in.rows; ++row ) {

// already around rotationCenter
// x' = x * cos(angle) - y * sin(angle)
float temp_columns( ( col - rotationCenter.x ) * (cosAngle) -
( row - rotationCenter.y ) * (sinAngle) +
rotationCenter.x );
// y' = x * sin(angle) + y * cos(angle)
float temp_rows ( ( col - rotationCenter.x ) * (sinAngle) +
( row - rotationCenter.y ) * (cosAngle) +
rotationCenter.y );

float max_col( ceil (temp_columns) );
float min_col( floor(temp_columns) );
float max_row( ceil (temp_rows) );
float min_row( floor(temp_rows) );

// clip all irrelevant parts
if ( max_col >= in.cols || max_row >= in.rows ||
min_col < 0 || min_row < 0 ) {
// don't draw
continue;
}

float deltaCol( temp_columns - min_col );
float deltaRow( temp_rows - min_row );

// left top, right top, left bottom and right bottom
Vec3b q12( in.at < Vec3b >( (int)min_row, (int)min_col ) );
Vec3b q22( in.at < Vec3b >( (int)min_row, (int)max_col ) );
Vec3b q11( in.at < Vec3b >( (int)max_row, (int)min_col ) );
Vec3b q21( in.at < Vec3b >( (int)max_row, (int)max_col ) );

// R1 - linear interpolation of bottom neighborhoods
double blueR1 ( ( 1 - deltaCol ) * q11[0] + deltaCol * q21[0] );
double greenR1 ( ( 1 - deltaCol ) * q11[1] + deltaCol * q21[1] );
double redR1 ( ( 1 - deltaCol ) * q11[2] + deltaCol * q21[2] );

// R2 - linear interpolation of top neighborhoods
double blueR2 ( ( 1 - deltaCol ) * q12[0] + deltaCol * q22[0] );
double greenR2 ( ( 1 - deltaCol ) * q12[1] + deltaCol * q22[1] );
double redR2 ( ( 1 - deltaCol ) * q12[2] + deltaCol * q22[2] );

// P - linear interpolation of R1 and R2
int blue ( (int)ceil( ( 1 - deltaRow ) * blueR2 + deltaRow * blueR1 ) );
int green( (int)ceil( ( 1 - deltaRow ) * greenR2 + deltaRow * greenR1 ) );
int red ( (int)ceil( ( 1 - deltaRow ) * redR2 + deltaRow * redR1 ) );

// Vec3b stands for 3-channel value, each channel is a byte
out.at < Vec3b >( row, col )[ 0 ] = int2uchar(blue);
out.at < Vec3b >( row, col )[ 1 ] = int2uchar(green);
out.at < Vec3b >( row, col )[ 2 ] = int2uchar(red);
}
}

return out;
}

int main( int ac, char ** av ) {
if ( ac < 2 ) {
print_help( av[ 0 ] );
return -1;
}

// In degrees
int step = 1, angle = 90;

VideoCapture capture;

// doesn't work properly
if ( capture.set(CV_CAP_PROP_FRAME_WIDTH, 1280 ) &&
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 720 ) ) {
cout << "Resolution : "
<< capture.get(CV_CAP_PROP_FRAME_WIDTH )
<< " x "
<< capture.get(CV_CAP_PROP_FRAME_HEIGHT )
<< endl;
} else {
cout << "There's some problem with VideoCapture::set()" << endl;
}

capture.open( atoi( av[ 1 ] ) );

while ( !capture.isOpened( ) ) {
print_help( av[ 0 ] );
cout << "Capture device " << atoi( av[ 1 ] ) << " failed to open!" << endl;
cout << "Connect capture device to PC\a" << endl;
system("pause");
cout << endl;
capture.open( atoi( av[ 1 ] ) );
}

cout << "Device " << atoi( av[ 1 ] ) << " is connected" << endl;

string original("Original");
string withInterpolation("With Bilinear Interpolation");

namedWindow( original, CV_WINDOW_AUTOSIZE );
namedWindow( withInterpolation, CV_WINDOW_AUTOSIZE);

Mat frame;

for ( ;; ) {
capture >> frame;
if ( frame.empty( ) )
break;

createTrackbar("Rotate", withInterpolation, &angle, 360, 0);

imshow( original, frame );

char key = ( char ) waitKey( 2 );
switch ( key ) {
case '+':
angle += step;
break;
case '-':
angle -= step;
break;
case 27:
case 'q':
return 0;
break;
}

Mat result;

Point2f rotationCenter( (float)( frame.cols / 2.0 ),
(float)( frame.rows / 2.0 ) );

result = rotate( frame, angle, rotationCenter );

// Note : mirror effect
// 1 says, that given frame will be flipped horizontally
flip(result,result, 1);

imshow( withInterpolation, result );

// test to compare my bilinear interpolation and of OpenCV
Mat temp;
warpAffine( frame, temp,
getRotationMatrix2D( rotationCenter, angle, (double)(1.0) ),
frame.size(), 1, 0 );
string openCVInterpolation("OpenCV Bilinear Interpolation");
namedWindow( openCVInterpolation, CV_WINDOW_AUTOSIZE );
createTrackbar("Rotate", openCVInterpolation, &angle, 360, 0);
flip(temp,temp, 1);
imshow( openCVInterpolation, temp );
}

return 0;
}

最佳答案

解决您的第二个问题 - 使用 OpenCV 设置 Lifecam 分辨率

我发现 Lifecam 仪表板可能会干扰 OpenCV Videocapture 调用。如果您使用控制面板中的程序和功能卸载 Lifecam,调用

capture.set(CV_CAP_PROP_FRAME_WIDTH, 1280)
capture.set(CV_CAP_PROP_FRAME_HEIGHT, 720)

将正常工作。

关于c++ - 使用 OpenCV 2.4.3 的双线性插值的 VideoCapture 旋转,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14573059/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com