1

머리카락의 구조를 캡처하기 위해 그라데이션 방향을 따라 지정된 점에서 큐를 그려야합니다. 그림 2와 같습니다. 및 그림 3을 참조하십시오. ACM 종이에서, 나는 여기에서 연결했다 : Single-View Hair Modeling for Portrait Manipulation. 이제 그라디언트로 방향 맵을 그렸습니다. 그러나 결과는 매우 혼란스러워 보입니다.이미지에서 머리카락 wisp 구조를 캡처하는 방법?

#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; 
} 

이 하나가 나에게 몇 가지 힌트를 줄 수 : 이 내 코드?

답변

0

귀하의 소벨은 x와 y에 대해 다른 코드가 있어야하는 동안 동일합니다. 0, 1, 1, 0입니다. 꼭대기에 cv8U를 심도 (inSobel)로 지정하고 플로트로 변환하여 느슨한 해상도와 부호를 지정하십시오. 또한 입력 해상도와 결과 이미지를 제공하십시오.

+0

안녕하세요 블라드, 답장을 보내 주셔서 감사합니다. 입력 및 출력 이미지를 제공하고 싶지만 이미지를 업로드하는 데 충분한 명성이 없습니다. Stackflow에서 질문하는 것은 이번이 처음이기 때문에. 그리고 당신은 소벨에서 CV_32F를 깊이로 사용해야한다는 것을 의미합니까? 나는 그것을 시도했다. 그러나 출력에는 많은 차이가 없었다. – sue

+0

당신은 또한 수평 및 수직 소파에 대해 0, 1 및 1,0로 코드를 변경해야합니다. 두 개의 수평선을 얻으면 각도가 엉망이됩니다. – Vlad