0

I am using opencv in python to try and detect shapes - in particular I want to be able to upload a picture of a wound - and for the system to find it. I think at the moment though its fixated on finding perfect circles.

input

enter image description here

output

enter image description here

current code looks like this

#/api/detect-shapes (comes back with the polygon shape data? comes back with modified images?)
@app.post("/api/detect-shapes")
async def post_detect_shapes(image_file: UploadFile = File(...)):
    # The image contents are read using await image_file.read()
    contents = await image_file.read()
    # converted to a NumPy array using 
    nparr = np.fromstring(contents, np.uint8)
    # decode the image data into a BGR image
    img = cv.imdecode(nparr, cv.IMREAD_COLOR)


    output = img.copy()

    detected_polygons = extract_polygon_data(output)

    for polygon in detected_polygons:
        cv.polylines(output, [np.array(polygon)], True, (0, 255, 0), 2)


    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    gray = cv.medianBlur(gray, 5)
    circles = cv.HoughCircles(gray, cv.HOUGH_GRADIENT, 1, 20, param1=50, param2=20, minRadius=0, maxRadius=0)
    detected_circles = np.uint16(np.around(circles))

    for (x, y, r) in detected_circles[0, :] :
       cv.circle(output, (x, y), r, (0, 255, 0), 3)
       cv.circle(output, (x, y), 2, (0, 255, 255), 3)

    #cv.imshow('output', output)
    #cv.waitKey(0)
    #cv.destroyAllWindows()

    #Convert NumPy array (img) to PIL image
    original_img_pil = Image.fromarray(cv.cvtColor(img, cv.COLOR_BGR2RGB))

    #Convert PIL image to base64-encoded string
    original_img_base64 = image_to_base64(original_img_pil)

    #Convert NumPy array (output) to PIL image
    output_img_pil = Image.fromarray(cv.cvtColor(output, cv.COLOR_BGR2RGB))

    #Convert PIL image to base64-encoded string
    output_img_base64 = image_to_base64(output_img_pil) 

    rn:int = random.randint(0, 100)
    return {'original_img_base64': original_img_base64, 'output_img_base64': output_img_base64, "detected_polygon": detected_polygons}

should I try and detect by contours?

Hough line transform to find polygons in an image

void detect_by_contour()
{
    //Following comments are written for non c++ programmers
    auto img = cv::imread("../forum_quest/data/yd8pA.png");
    if(img.empty()){
        throw std::runtime_error("cannot open image");
    }

    cv::Mat gray_img;
    cv::cvtColor(img, gray_img, CV_BGR2GRAY);
    cv::Mat thin_img;
    //make your lines as thin as possible
    morphology_skeleton(gray_img, thin_img);

    std::vector<std::vector<cv::Point>> contours;
    cv::findContours(thin_img, contours, cv::RETR_EXTERNAL,
                     cv::CHAIN_APPROX_SIMPLE);
    //remove contour if the area less than 100
    auto it = std::remove_if(std::begin(contours), std::end(contours),
                   [](std::vector<cv::Point> const &a)
    {
        return cv::boundingRect(a).area() < 100;
    });
    //remove_if move unwanted elements to the backyard of the containers
    //you need to call the erase function of the containers to remove
    //unwanted elements
    contours.erase(it, std::end(contours));

    //contour_analyzer is a class used to print out statistic info
    //of the contour
    ocv::contour_analyzer analyzer;
    //print_contour_attribute_name print out the attribute names
    //of the contours as following
    //CArea   |   BArea   | Perimeter |   Aspect  |   Extent  |  Solidity |  PolySize
    ocv::print_contour_attribute_name(std::cout);
    for(size_t i = 0; i != contours.size(); ++i){
        cv::drawContours(img, contours, static_cast<int>(i), {0,255,0}, 2);        
        std::cout<<analyzer.analyze(contours[i], 0.1);
        cv::imshow("img", img);
        cv::waitKey();
    }
    cv::imwrite("polygon.jpg", img);
}
The Old County
  • 89
  • 13
  • 59
  • 129

0 Answers0