gpt4 book ai didi

c++ - Farneback 光流 - 处理视野外的像素、流结果错误的像素、不同尺寸的图像

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:43:48 24 4
gpt4 key购买 nike

我正在写论文,任务的一部分是在图像之间进行插值以创建中间图像。这项工作必须使用 openCV 2.4.13 在 c++ 中完成。到目前为止,我找到的最佳解决方案是计算光流和重新映射。但是这个解决方案有两个问题我自己无法解决:

  • 有些像素应该不在视线范围内(例如图像底部),但实际上没有。
  • 一些像素没有移动,产生了扭曲的结果(沙发的右上部分)

是什么让流程和重新映射方法更好:

  • 均衡强度。这是我被允许做的。您可以通过比较沙发形式(重映射图像和原始图像的中心)来检查结果。
  • 缩小图像尺寸。我不允许这样做,因为我需要相同大小的输出。有没有办法重新缩放光流结果以获得更大的重新映射图像?

尝试过但失败的其他方法:

  • cuda::插值帧。创造令人难以置信的重影。
  • 使用 cv::addWeighted 混合图像。更糟糕的重影。

下面是我目前使用的代码。和图片:dropbox link with input and result images

int main(){

cv::Mat second, second_gray, cutout, cutout_gray, flow_n;
second = cv::imread( "/home/zuze/Desktop/forstack/second_L.jpg", 1 );
cutout = cv::imread("/home/zuze/Desktop/forstack/cutout_L.png", 1);
cvtColor(second, second_gray, CV_BGR2GRAY);
cvtColor(cutout, cutout_gray, CV_RGB2GRAY );

///----------COMPUTE OPTICAL FLOW AND REMAP -----------///
cv::calcOpticalFlowFarneback( second_gray, cutout_gray, flow_n, 0.5, 3, 15, 3, 5, 1.2, 0 );
cv::Mat remap_n; //looks like it's drunk.
createNewFrame(remap_n, flow_n, 1, second, cutout );
cv::Mat cflow_n;
cflow_n = cutout_gray;
cvtColor(cflow_n, cflow_n, CV_GRAY2BGR);
drawOptFlowMap(flow_n, cflow_n, 10, CV_RGB(0,255,0));

///--------EQUALIZE INTENSITY, COMPUTE OPTICAL FLOW AND REMAP ----///
cv::Mat cutout_eq, second_eq;
cutout_eq= equalizeIntensity(cutout);
second_eq= equalizeIntensity(second);

cv::Mat flow_eq, cutout_eq_gray, second_eq_gray, cflow_eq;
cvtColor( cutout_eq, cutout_eq_gray, CV_RGB2GRAY );
cvtColor( second_eq, second_eq_gray, CV_RGB2GRAY );

cv::calcOpticalFlowFarneback( second_eq_gray, cutout_eq_gray, flow_eq, 0.5, 3, 15, 3, 5, 1.2, 0 );
cv::Mat remap_eq;
createNewFrame(remap_eq, flow_eq, 1, second, cutout_eq );
cflow_eq = cutout_eq_gray;
cvtColor(cflow_eq, cflow_eq, CV_GRAY2BGR);
drawOptFlowMap(flow_eq, cflow_eq, 10, CV_RGB(0,255,0));

cv::imshow("remap_n", remap_n);
cv::imshow("remap_eq", remap_eq);
cv::imshow("cflow_eq", cflow_eq);
cv::imshow("cflow_n", cflow_n);
cv::imshow("sec_eq", second_eq);
cv::imshow("cutout_eq", cutout_eq);
cv::imshow("cutout", cutout);
cv::imshow("second", second);

cv::waitKey();

return 0;

重映射函数,用于创建中间图像:

void createNewFrame(cv::Mat & frame, const cv::Mat & flow, float shift, cv::Mat & prev, cv::Mat &next){
cv::Mat mapX(flow.size(), CV_32FC1);
cv::Mat mapY(flow.size(), CV_32FC1);
cv::Mat newFrame;
for (int y = 0; y < mapX.rows; y++){
for (int x = 0; x < mapX.cols; x++){
cv::Point2f f = flow.at<cv::Point2f>(y, x);
mapX.at<float>(y, x) = x + f.x*shift;
mapY.at<float>(y, x) = y + f.y*shift;
}
}
remap(next, newFrame, mapX, mapY, cv::INTER_LANCZOS4);
frame = newFrame;
cv::waitKey();
}

以 vector 形式显示光流的函数:

void drawOptFlowMap (const cv::Mat& flow, cv::Mat& cflowmap, int step, const cv::Scalar& color) {
cv::Point2f sum; //zz
std::vector<float> all_angles;
int count=0; //zz
float angle, sum_angle=0; //zz
for(int y = 0; y < cflowmap.rows; y += step)
for(int x = 0; x < cflowmap.cols; x += step)
{
const cv::Point2f& fxy = flow.at< cv::Point2f>(y, x);
if((fxy.x != fxy.x)||(fxy.y != fxy.y)){ //zz, for SimpleFlow
//std::cout<<"meh"; //do nothing
}
else{
line(cflowmap, cv::Point(x,y), cv::Point(cvRound(x+fxy.x), cvRound(y+fxy.y)),color);
circle(cflowmap, cv::Point(cvRound(x+fxy.x), cvRound(y+fxy.y)), 1, color, -1);
sum +=fxy;//zz
angle = atan2(fxy.y,fxy.x);
sum_angle +=angle;
all_angles.push_back(angle*180/M_PI);
count++; //zz
}
}
}

均衡图像强度的功能,以获得更好的结果:

cv::Mat equalizeIntensity(const cv::Mat& inputImage){
if(inputImage.channels() >= 3){
cv::Mat ycrcb;
cvtColor(inputImage,ycrcb,CV_BGR2YCrCb);
std::vector<cv::Mat> channels;
cv::split(ycrcb,channels);
cv::equalizeHist(channels[0], channels[0]);
cv::Mat result;
cv::merge(channels,ycrcb);
cvtColor(ycrcb,result,CV_YCrCb2BGR);
return result;
}
return cv::Mat();
}

回顾一下,我的问题:

  • 是否可以调整 Farneback 光流的大小以应用于 2 倍大的图像?
  • 如何处理超出视野的像素,例如图像底部的像素(棕色木质部分应该消失)。
  • 如何处理由于没有为这些像素计算光流而产生的失真,而周围的许多像素都有运动? (沙发右上角,狮子雕像在重新映射的图像中有一只鬼手)。

最佳答案

使用 OpenCV 的Farneback 光流,您只能得到像素位移的粗略估计,因此结果图像上会出现失真。

我不认为光流是实现恕我直言的目标的方法。相反,我建议您在此处查看 Image/Pixel Registration 实例:http://docs.opencv.org/trunk/db/d61/group__reg.html

图像/像素配准 是匹配两幅图像像素的科学。关于这个尚未准确解决的复杂的重要主题,正在进行积极的研究。

关于c++ - Farneback 光流 - 处理视野外的像素、流结果错误的像素、不同尺寸的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43512039/

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