Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Opencv 如何从图像中捕捉发绺结构?_Opencv_Image Processing_Computer Vision_Image Manipulation - Fatal编程技术网

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

Opencv 如何从图像中捕捉发绺结构?,opencv,image-processing,computer-vision,image-manipulation,Opencv,Image Processing,Computer Vision,Image Manipulation,我想从一个指定的点沿着它的梯度方向画一条线索,以捕捉发丝的结构。如图2所示。图3。从ACM的一篇论文中,我链接到这里:。现在我用渐变绘制方向图,但结果看起来很混乱。 这是我的代码: #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> using namespace cv; using namespace std;

我想从一个指定的点沿着它的梯度方向画一条线索,以捕捉发丝的结构。如图2所示。图3。从ACM的一篇论文中,我链接到这里:。现在我用渐变绘制方向图,但结果看起来很混乱。 这是我的代码:

#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;
}
#包括
#包括
#包括
使用名称空间cv;
使用名称空间std;
int main(int argv,char*argc[])
{
Mat image=imread(“wavy.jpg”,0);
如果(!image.data)
返回-1;
Mat sobelX1;
Sobel(图像,sobelX1,CV_8U,1,0,3);
//imshow(“X方向”,sobelX);
Mat sobelY1;
Sobel(图像,sobelY1,CV_8U,1,0,3);
//imshow(“Y方向”,sobelY);
Mat sobelX,sobelY;
sobelX1.convertTo(sobelX,CV_32F,1./255);
sobelY1.convertTo(sobelY,CV_32F,1./255);
双l_max=-10;
对于(int y=0;yl_max)l_max=l;
}
}
对于(int y=0;y0)
{
double spinSize=5.0*l/l_max;//根据箭头长度使旋转大小正常化的因子
CvPoint p2=CvPoint(p.x+(int)(dx),p.y+(int)(dy));
线(图像,p,p2,CV_RGB(0255,0),1,CV_AA);
双角度;//绘制箭头的旋转
角度=atan2((双)p.y-p2.y,(双)p.x-p2.x);
p、 x=(int)(p2.x+spinSize*cos(角度+3.1416/4));
p、 y=(int)(p2.y+spinSize*sin(角度+3.1416/4));
线(图像,p,p2,CV_RGB(0255,0),1,CV_AA,0);
}
}
}
imshow(“方向图”,图像);
等待键(0);
返回0;
}

谁能给我一些提示吗

您的Sobel是相同的,但它们应该具有不同的x和y代码。0、1和1、0。除此之外,通过将cv8U指定为深度inBel,然后转换为float,可以降低分辨率并进行签名。另外,请提供输入分辨率和结果图像

嗨,弗拉德,谢谢你的回复。我想提供输入和输出图像,但我没有足够的声誉上传图像。因为这是我第一次问关于stackflow的问题。你是说我应该用CV_32F作为Sobel的深度?我试过了,但是输出没有太大的差别。您还应该将水平和垂直清醒的代码更改为0、1和1,0。如果你得到两个水平的,那么你的角度就会被弄乱。