如何从图像中捕捉发缕结构?

时间:2014-04-14 14:42:46

标签: opencv image-processing computer-vision image-manipulation

我想从指定点沿其渐变方向绘制一个提示,以捕捉发缕的结构。如图2所示。和图3。在ACM论文中,我链接到这里:Single-View Hair Modeling for Portrait Manipulation。现在我通过渐变绘制方向图,但结果看起来非常混乱。 这是我的代码:

#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main(int argv, char* argc[])
{
    Mat image = imread("wavy.jpg", 0);
    if(!image.data)
        return -1;

    Mat sobelX1;
    Sobel(image, sobelX1, CV_8U, 1, 0, 3);
    //imshow("X direction", sobelX);

    Mat sobelY1;
    Sobel(image, sobelY1, CV_8U, 1, 0, 3);
    //imshow("Y direction", sobelY);

    Mat sobelX, sobelY;
    sobelX1.convertTo(sobelX, CV_32F, 1./255);
    sobelY1.convertTo(sobelY, CV_32F, 1./255);

    double l_max = -10;
    for (int y = 0; y < image.rows; y+=3)                                                           // First iteration, to compute the maximum l (longest flow)
    {
        for (int x = 0; x < image.cols; x+=3)
        {
            double dx = sobelX.at<float>(y, x);                                                        // Gets X component of the flow
            double dy = sobelY.at<float>(y, x);                                                        // Gets Y component of the flow

            CvPoint p = cvPoint(y, x);

            double l = sqrt(dx*dx + dy*dy);                                                             // This function sets a basic threshold for drawing on the image

            if(l>l_max) l_max = l;
        }
    }

    for (int y = 0; y < image.rows; y+=3)
    {
        for (int x = 0; x < image.cols; x+=3)
    {
        double dx = sobelX.at<float>(y, x);                                                        // Gets X component of the flow
        double dy = sobelY.at<float>(y, x);                                                        // Gets Y component of the flow

        CvPoint p = cvPoint(x, y);

        double l = sqrt(dx*dx + dy*dy);                                                             // This function sets a basic threshold for drawing on the image
        if (l > 0)
        {
            double spinSize = 5.0 * l/l_max;                                                        // Factor to normalise the size of the spin depending on the length of the arrow

            CvPoint p2 = cvPoint(p.x + (int)(dx), p.y + (int)(dy));
            line(image, p, p2, CV_RGB(0,255,0), 1, CV_AA);

            double angle;                                                                           // Draws the spin of the arrow
            angle = atan2( (double) p.y - p2.y, (double) p.x - p2.x);

            p.x = (int) (p2.x + spinSize * cos(angle + 3.1416 / 4));
            p.y = (int) (p2.y + spinSize * sin(angle + 3.1416 / 4));
            line(image, p, p2, CV_RGB(0,255,0), 1, CV_AA, 0 );
        }
    }
    }

    imshow("Orientation Map", image);
    waitKey(0);
    return 0;
}

任何人都可以给我一些提示吗?

1 个答案:

答案 0 :(得分:0)

你的Sobels是相同的,而他们应该有不同的x和y代码。 0,1和1,最重要的是你通过将sv8U指定为sobel中的深度并且仅转换为float来松散分辨率和符号。还请提供输入分辨率和结果图像。