首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >远背光流-处理视野外的像素,流结果错误的像素,不同大小的图像。

远背光流-处理视野外的像素,流结果错误的像素,不同大小的图像。
EN

Stack Overflow用户
提问于 2017-04-20 06:41:14
回答 1查看 938关注 0票数 2

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

  • 有些像素应该从的视图中移出(例如,图像的底部),但它们没有。
  • 一些像素不移动,造成扭曲的结果(沙发右上半部分)

是什么使flow&remap方法更好的

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

其他方法尝试过,失败了

  • 库达::插值框架。创造了不可思议的幽灵。
  • 将图像与cv::addWeighted混合。更糟的是幽灵。

下面是我目前正在使用的代码。图片:带有输入和结果图像的dropbox链接

int main(){

代码语言:javascript
复制
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;

}

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

代码语言:javascript
复制
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();
}

以矢量形式显示光流的功能:

代码语言:javascript
复制
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
            }
        }
}

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

代码语言:javascript
复制
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光流的大小,以适用于2x更大的图像?
  • 如何处理像素,如我的图像底部的(棕色木质部分应该消失)。
  • 如何处理由于光流没有为这些像素计算,而周围的许多像素都有运动而产生的失真?(沙发右上角,狮子雕像有一只鬼手在重绘的图像中)。
EN

回答 1

Stack Overflow用户

发布于 2017-04-20 09:06:59

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

我不认为光流是你试图实现IMHO的方法。相反,我建议您在这里查看图像/像素注册,例如:reg.html

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43512039

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档