본문 바로가기
Projects/Foot

I am trying to find between the toes using opencv for photos taken from the top of the feet.

by wenect 2023. 4. 13.

opencv 발가락 사이의 위치를 구하기

  1. Load the image using imread function in OpenCV for Unity.
  2. Mat img = Cv2.ImRead("path/to/image.jpg");
  3. Convert the image to grayscale using the cvtColor function.
  4. Mat grayImg = new Mat();
    Cv2.CvtColor(img, grayImg, ColorConversionCodes.BGR2GRAY);
  5. Apply a threshold to the image to separate the toes from the rest of the foot using the threshold function.
  6. Mat thresholdImg = new Mat(); Cv2.Threshold(grayImg, thresholdImg, 0, 255, ThresholdTypes.Binary);
  7. Apply a morphological opening operation to remove small noise in the image using the morphologyEx function.
  8. Mat morphImg = new Mat(); Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(5, 5)); Cv2.MorphologyEx(thresholdImg, morphImg, MorphTypes.Open, kernel);
  9. Find the contours in the image using the findContours function.
  10. List<Point[][]> contoursList = new List<Point[][]>(); Mat hierarchy = new Mat(); Cv2.FindContours(morphImg, out contoursList, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);
  11. Iterate through the contours and find the one that represents the space between the toes using some heuristics, such as size and shape.
  12. Draw the contour on the original image using the drawContours function.
  13. Cv2.DrawContours(img, contoursList, -1, new Scalar(0, 0, 255), 2);
  14. Display the image using the imshow function.
  15. Cv2.ImShow("Toes Space", img);
  16. Here is an example code that demonstrates the above steps:
scss
using UnityEngine;
using OpenCvSharp;
using OpenCvSharp.Unity;

public class ToesSpaceDetection : MonoBehaviour
{
    public string imagePath = "path/to/image.jpg";

    void Start()
    {
        // Load the image
        Mat img = Cv2.ImRead(imagePath);

        // Convert the image to grayscale
        Mat grayImg = new Mat();
        Cv2.CvtColor(img, grayImg, ColorConversionCodes.BGR2GRAY);

        // Apply a threshold to the image
        Mat thresholdImg = new Mat();
        Cv2.Threshold(grayImg, thresholdImg, 0, 255, ThresholdTypes.Binary);

        // Apply a morphological opening operation to remove small noise in the image
        Mat morphImg = new Mat();
        Mat kernel = Cv2.GetStructuringElement(MorphShapes.Ellipse, new Size(5, 5));
        Cv2.MorphologyEx(thresholdImg, morphImg, MorphTypes.Open, kernel);

        // Find the contours in the image
        List<Point[][]> contoursList = new List<Point[][]>();
        Mat hierarchy = new Mat();
        Cv2.FindContours(morphImg, out contoursList, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);

        // Iterate through the contours and find the one that represents the space between the toes
        int maxAreaIndex = -1;
        double maxArea = 0;
        for (int i = 0; i < contoursList.Count; i++)
        {
            double area = Cv2.ContourArea(contoursList[i]);
            if (area > maxArea)
            {                
             	// Check if the contour is approximately rectangular
            	RotatedRect boundingRect = Cv2.MinAreaRect(contoursList[i]);
            	float aspectRatio = boundingRect.Size.Height / boundingRect.Size.Width;
            	if (aspectRatio > 0.2 && aspectRatio < 0.8)
            	{
                	maxArea = area;
                	maxAreaIndex = i;
            	}
        	}
    }

    // Draw the contour on the original image
    if (maxAreaIndex != -1)
    {
        Cv2.DrawContours(img, contoursList, maxAreaIndex, new Scalar(0, 0, 255), 2);
    }

    // Display the image
    Cv2.ImShow("Toes Space", img);
}


이 코드에서는 `Cv2.ContourArea` 함수를 사용하여 각 윤곽선의 면적을 계산하고 `Cv2.MinAreaRect` 함수를 사용하여 각 윤곽선의 경계 사각형을 얻습니다. 그런 다음 임계값을 사용하여 경계 사각형의 종횡비가 대략 직사각형인지 확인하고 이 조건을 만족하는 가장 큰 면적의 윤곽선을 발가락 사이의 공간을 나타내는 윤곽선으로 선택합니다.

대략적인 직사각형 윤곽을 확인하는 데 사용되는 임계값은 사용 중인 특정 이미지에 따라 조정해야 할 수 있습니다. 또한 이 방법은 발가락이 잘 분리되지 않았거나 옷이나 기타 물체에 의해 가려진 이미지에는 적합하지 않을 수 있습니다.

 

ToesSpaceDetection 스크립트를 구현한 후 Unity 게임 오브젝트에 연결하고 장면을 실행하여 제공된 이미지에서 발가락 사이의 공간을 감지할 수 있습니다.

입력 이미지를 조정하려면 스크립트의 imagePath 변수를 자신의 이미지 경로로 수정하면 됩니다.

특정 이미지 데이터에 더 잘 맞도록 스크립트의 '시작' 기능에서 대략적인 직사각형 윤곽을 확인하는 데 사용되는 임계값을 조정할 수도 있습니다.

if (aspectRatio > 0.2 && aspectRatio < 0.8)

이 코드 줄에서 임계값은 허용되는 최소 및 최대 종횡비에 대해 각각 '0.2' 및 '0.8'로 설정됩니다. 이 값을 조정하여 특정 이미지의 윤곽선 종횡비에 더 잘 맞도록 할 수 있습니다.

특정 이미지에 대한 임계값을 조정하면 이 스크립트를 사용하여 발의 하향식 이미지에서 발가락 사이의 공간을 감지할 수 있습니다.

ToesSpaceDetection 스크립트의 결과를 개선하기 위해 흐림 또는 가장자리 감지와 같은 추가 이미지 처리 기술을 적용하여 발가락 사이의 공간을 더 잘 분리할 수 있습니다.

예를 들어 임계값을 지정하기 전에 그레이스케일 이미지에 가우시안 블러를 적용하여 발가락 사이의 공간 감지를 방해할 수 있는 작은 세부 정보를 제거할 수 있습니다.

Cv2.GaussianBlur(grayImg, grayImg, new Size(5, 5), 0);

또한 임계값 이미지에 Canny 가장자리 감지를 적용하여 발가락 사이 공간의 더 정확한 가장자리를 얻을 수 있습니다.

Mat edgesImg = new Mat();
Cv2.Canny(morphImg, edgesImg, 50, 150);

그런 다음 가장자리 이미지에서 윤곽선을 찾고 동일한 휴리스틱을 수행하여 발가락 사이의 공간을 나타내는 윤곽선을 선택할 수 있습니다.

List<Point[][]> contoursList = new List<Point[][]>();
Mat hierarchy = new Mat();
Cv2.FindContours(edgesImg, out contoursList, hierarchy, RetrievalModes.List, ContourApproximationModes.ApproxSimple);

int maxAreaIndex = -1;
double maxArea = 0;
for (int i = 0; i < contoursList.Count; i++)
{
    double area = Cv2.ContourArea(contoursList[i]);
    if (area > maxArea)
    {
        maxArea = area;
        maxAreaIndex = i;
    }
}

if (maxAreaIndex != -1)
{
    Cv2.DrawContours(img, contoursList, maxAreaIndex, new Scalar(0, 0, 255), 2);
}

흐림 및 가장자리 감지와 같은 추가 이미지 처리 기술을 사용하여 잠재적으로 ToesSpaceDetection 스크립트의 정확도를 개선하고 더 정확한 결과를 얻을 수 있습니다.

'Projects > Foot' 카테고리의 다른 글

solecooler  (0) 2024.01.12
발의 아치를 찾는 알고리즘  (0) 2023.04.13

댓글