PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, July 29, 2022

[FIXED] how can we calculate the area of root image?

 July 29, 2022     area, image, opencv, python, root     No comments   

Issue

in my project i need to calculate the area of small plant root image.

rootimage

i have used the following two codes but i still doubt these:

import cv2
image = cv2.imread('D:/R4-15.TIF')
img_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 180, 255, cv2.THRESH_BINARY)
cv2.imshow('Binary', thresh)
contours, hierarchy = cv2.findContours(image=thresh, mode=cv2.RETR_TREE, method=cv2.CHAIN_APPROX_NONE)
image_copy = image.copy()
cv2.drawContours(image=image_copy, contours=contours, contourIdx=-1, color=(0, 255, 0), thickness=-1, lineType=cv2.LINE_AA)
               
cv2.imshow('Contour_image', image_copy)
cv2.waitKey(0)
cv2.imwrite('contours_image1.jpg', image_copy)
cv2.destroyAllWindows()

cnt = contours[0]
area= cv2.contourArea(cnt)
print(area)      

cv2.waitKey(0)
cv2.destroyAllWindows()

import cv2
import numpy as np
img = cv2.imread('D:/R4-16.TIF')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(gray,165,255,cv2.THRESH_BINARY)
cv2.imshow("Mask", thresh)
cv2.waitKey(0)
cv2.destroyAllWindows()
area2 = cv2.countNonZero(thresh)
print(area2)

Solution

If your thresholded image has no noise, then countNonZero is fine.

But if after threshold you still have some noise, which is usually small black dots scattered here and there, then better to filter them out.

One of possible ways is to apply morphological opening, see Morphological operations. But it definately also alters ground truth root image.

I propose to use connectedComponentsWithStats

Call it against your thresholded root image.

One of returned values is stats which will also hold area for each connected component. Then you can drop all small components which is a noise, and pickup one or few largest black components and take their area.

More about connected components in wiki

Call example


# ...
# Put it at the end of you second snippet,
# where you get thresholded image

num_components, labels, stats, centroids = \
    cv2.connectedComponentsWithStats(thresh)

# Here you can also use something like this:
# total_area = list(itertools.accumulate(
#    stats, lambda t, x: t + x[cv2.CC_STAT_AREA])
# )[-1]

areas = stats[:, cv2.CC_STAT_AREA]
areas = list(sorted(areas))

assert \
    len(areas) >= 2, \
    "We expect at least two components: white area" \
    " and at least one root fragment."

# We suppose that white area is the biggest one, thus
# we have to count everything except the last item in sorted
# list.

total_area = 0
noise_threshold = 5 # If area is less than 5 pixels we drop it
for i, area in enumerate(areas[:-1]):
    print(f"Area of root part #{i} is: {area}")
    if area > noise_threshold:
        total_area += area

print(f"Total area is: {total_area}")


Answered By - Stepan Dyatkovskiy
Answer Checked By - Clifford M. (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing