Image analysis, object shape, center and extrema












0















I wrote a program to build a threshold from a grayscale image and find its lower object's center. This is further used to draw a geometry (line) into the object. cv2.PCACompute() function is used to find the center of the object. After this is done, I can draw lines to match the object's approximate shape and do further analysis.



So:



The extrema of the object are the important thing I need to find, not the center. But for them to be calculated I need to draw a line originating from the center. Problem with that is, that I need to tell the program the size of the object. Right now I am trying to automate this by detecting the extrema of the object instead of the center. I wondered if you can help me with that.



Input Image:



enter image description here



First a Threshold is built and the upper object removed from it:



import cv2
import numpy as np

#required to draw the length of the lins, originating from the core of object
scale = 20 #factor by which original image was scaled up
shard_size = 12*scale #length of object

#import image
img = cv2.imread('img.png', 0)

#build threshold
_, thresh = cv2.threshold(img,
235,
255,
cv2.THRESH_BINARY)

#remove upper object from image
z = 0
for x in thresh[::-1]:
v = 0
for el in x:
if el > 0:
break
v += 1
z += 1
if el > 0:
thresh[:int(-z-shard_size-2*scale)] = 0
break


enter image description here



As you can see, the object is cut at the top. This is a clunky way of doing this. In the next step cv2.PCACompute() is used to find the center of the object and determine the direction of its extrema. With shard_size provided, a line can be drawn in the direction of the object extrema.



#compute geometry of object (center + line extrema)
mat = np.argwhere(thresh == 255)
mat[:, [0, 1]] = mat[:, [1, 0]]
mat = np.array(mat).astype(np.float32)
m, e = cv2.PCACompute(mat, mean = np.array())

#determine coordinates of object (center + line extrema)
center = tuple(m[0])
endpoint1 = tuple(m[0] - e[0] * shard_size/2)
endpoint2 = tuple(m[0] + e[0] * shard_size/2)

#draw line into object
red_color = (0, 0, 255)
coord1 = endpoint1
coord2 = endpoint2
cv2.circle(img, center, 1, red_color)
cv2.line(img, coord1, coord2, red_color)

#save output img
cv2.imwrite('output_img.png', img)


enter image description here



How do I find the extrema of the object instead of the center, so I do not need to give the program the shard_size Input anymore?










share|improve this question























  • Is there something like a closest-fit bounding box (not axis aligned)?

    – Vroomfondel
    Nov 27 '18 at 7:59











  • I am sorry, what do you mean?

    – Artur Müller Romanov
    Nov 27 '18 at 8:06











  • After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

    – Vroomfondel
    Nov 27 '18 at 8:22
















0















I wrote a program to build a threshold from a grayscale image and find its lower object's center. This is further used to draw a geometry (line) into the object. cv2.PCACompute() function is used to find the center of the object. After this is done, I can draw lines to match the object's approximate shape and do further analysis.



So:



The extrema of the object are the important thing I need to find, not the center. But for them to be calculated I need to draw a line originating from the center. Problem with that is, that I need to tell the program the size of the object. Right now I am trying to automate this by detecting the extrema of the object instead of the center. I wondered if you can help me with that.



Input Image:



enter image description here



First a Threshold is built and the upper object removed from it:



import cv2
import numpy as np

#required to draw the length of the lins, originating from the core of object
scale = 20 #factor by which original image was scaled up
shard_size = 12*scale #length of object

#import image
img = cv2.imread('img.png', 0)

#build threshold
_, thresh = cv2.threshold(img,
235,
255,
cv2.THRESH_BINARY)

#remove upper object from image
z = 0
for x in thresh[::-1]:
v = 0
for el in x:
if el > 0:
break
v += 1
z += 1
if el > 0:
thresh[:int(-z-shard_size-2*scale)] = 0
break


enter image description here



As you can see, the object is cut at the top. This is a clunky way of doing this. In the next step cv2.PCACompute() is used to find the center of the object and determine the direction of its extrema. With shard_size provided, a line can be drawn in the direction of the object extrema.



#compute geometry of object (center + line extrema)
mat = np.argwhere(thresh == 255)
mat[:, [0, 1]] = mat[:, [1, 0]]
mat = np.array(mat).astype(np.float32)
m, e = cv2.PCACompute(mat, mean = np.array())

#determine coordinates of object (center + line extrema)
center = tuple(m[0])
endpoint1 = tuple(m[0] - e[0] * shard_size/2)
endpoint2 = tuple(m[0] + e[0] * shard_size/2)

#draw line into object
red_color = (0, 0, 255)
coord1 = endpoint1
coord2 = endpoint2
cv2.circle(img, center, 1, red_color)
cv2.line(img, coord1, coord2, red_color)

#save output img
cv2.imwrite('output_img.png', img)


enter image description here



How do I find the extrema of the object instead of the center, so I do not need to give the program the shard_size Input anymore?










share|improve this question























  • Is there something like a closest-fit bounding box (not axis aligned)?

    – Vroomfondel
    Nov 27 '18 at 7:59











  • I am sorry, what do you mean?

    – Artur Müller Romanov
    Nov 27 '18 at 8:06











  • After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

    – Vroomfondel
    Nov 27 '18 at 8:22














0












0








0








I wrote a program to build a threshold from a grayscale image and find its lower object's center. This is further used to draw a geometry (line) into the object. cv2.PCACompute() function is used to find the center of the object. After this is done, I can draw lines to match the object's approximate shape and do further analysis.



So:



The extrema of the object are the important thing I need to find, not the center. But for them to be calculated I need to draw a line originating from the center. Problem with that is, that I need to tell the program the size of the object. Right now I am trying to automate this by detecting the extrema of the object instead of the center. I wondered if you can help me with that.



Input Image:



enter image description here



First a Threshold is built and the upper object removed from it:



import cv2
import numpy as np

#required to draw the length of the lins, originating from the core of object
scale = 20 #factor by which original image was scaled up
shard_size = 12*scale #length of object

#import image
img = cv2.imread('img.png', 0)

#build threshold
_, thresh = cv2.threshold(img,
235,
255,
cv2.THRESH_BINARY)

#remove upper object from image
z = 0
for x in thresh[::-1]:
v = 0
for el in x:
if el > 0:
break
v += 1
z += 1
if el > 0:
thresh[:int(-z-shard_size-2*scale)] = 0
break


enter image description here



As you can see, the object is cut at the top. This is a clunky way of doing this. In the next step cv2.PCACompute() is used to find the center of the object and determine the direction of its extrema. With shard_size provided, a line can be drawn in the direction of the object extrema.



#compute geometry of object (center + line extrema)
mat = np.argwhere(thresh == 255)
mat[:, [0, 1]] = mat[:, [1, 0]]
mat = np.array(mat).astype(np.float32)
m, e = cv2.PCACompute(mat, mean = np.array())

#determine coordinates of object (center + line extrema)
center = tuple(m[0])
endpoint1 = tuple(m[0] - e[0] * shard_size/2)
endpoint2 = tuple(m[0] + e[0] * shard_size/2)

#draw line into object
red_color = (0, 0, 255)
coord1 = endpoint1
coord2 = endpoint2
cv2.circle(img, center, 1, red_color)
cv2.line(img, coord1, coord2, red_color)

#save output img
cv2.imwrite('output_img.png', img)


enter image description here



How do I find the extrema of the object instead of the center, so I do not need to give the program the shard_size Input anymore?










share|improve this question














I wrote a program to build a threshold from a grayscale image and find its lower object's center. This is further used to draw a geometry (line) into the object. cv2.PCACompute() function is used to find the center of the object. After this is done, I can draw lines to match the object's approximate shape and do further analysis.



So:



The extrema of the object are the important thing I need to find, not the center. But for them to be calculated I need to draw a line originating from the center. Problem with that is, that I need to tell the program the size of the object. Right now I am trying to automate this by detecting the extrema of the object instead of the center. I wondered if you can help me with that.



Input Image:



enter image description here



First a Threshold is built and the upper object removed from it:



import cv2
import numpy as np

#required to draw the length of the lins, originating from the core of object
scale = 20 #factor by which original image was scaled up
shard_size = 12*scale #length of object

#import image
img = cv2.imread('img.png', 0)

#build threshold
_, thresh = cv2.threshold(img,
235,
255,
cv2.THRESH_BINARY)

#remove upper object from image
z = 0
for x in thresh[::-1]:
v = 0
for el in x:
if el > 0:
break
v += 1
z += 1
if el > 0:
thresh[:int(-z-shard_size-2*scale)] = 0
break


enter image description here



As you can see, the object is cut at the top. This is a clunky way of doing this. In the next step cv2.PCACompute() is used to find the center of the object and determine the direction of its extrema. With shard_size provided, a line can be drawn in the direction of the object extrema.



#compute geometry of object (center + line extrema)
mat = np.argwhere(thresh == 255)
mat[:, [0, 1]] = mat[:, [1, 0]]
mat = np.array(mat).astype(np.float32)
m, e = cv2.PCACompute(mat, mean = np.array())

#determine coordinates of object (center + line extrema)
center = tuple(m[0])
endpoint1 = tuple(m[0] - e[0] * shard_size/2)
endpoint2 = tuple(m[0] + e[0] * shard_size/2)

#draw line into object
red_color = (0, 0, 255)
coord1 = endpoint1
coord2 = endpoint2
cv2.circle(img, center, 1, red_color)
cv2.line(img, coord1, coord2, red_color)

#save output img
cv2.imwrite('output_img.png', img)


enter image description here



How do I find the extrema of the object instead of the center, so I do not need to give the program the shard_size Input anymore?







python opencv object-detection






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 7:42









Artur Müller RomanovArtur Müller Romanov

358315




358315













  • Is there something like a closest-fit bounding box (not axis aligned)?

    – Vroomfondel
    Nov 27 '18 at 7:59











  • I am sorry, what do you mean?

    – Artur Müller Romanov
    Nov 27 '18 at 8:06











  • After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

    – Vroomfondel
    Nov 27 '18 at 8:22



















  • Is there something like a closest-fit bounding box (not axis aligned)?

    – Vroomfondel
    Nov 27 '18 at 7:59











  • I am sorry, what do you mean?

    – Artur Müller Romanov
    Nov 27 '18 at 8:06











  • After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

    – Vroomfondel
    Nov 27 '18 at 8:22

















Is there something like a closest-fit bounding box (not axis aligned)?

– Vroomfondel
Nov 27 '18 at 7:59





Is there something like a closest-fit bounding box (not axis aligned)?

– Vroomfondel
Nov 27 '18 at 7:59













I am sorry, what do you mean?

– Artur Müller Romanov
Nov 27 '18 at 8:06





I am sorry, what do you mean?

– Artur Müller Romanov
Nov 27 '18 at 8:06













After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

– Vroomfondel
Nov 27 '18 at 8:22





After the threshold operation you are left with a binary image - usually the light pixels comprise a ROI "region of interest" which can be subjected to certain operations of its geometric properties: area, smallest enclosing circle, axis aligned bounding box, smallest bounding box, etc. The last one could be your best bet to pull out the major axis length. Alternatively there maybe is a "maximum diameter" which tells more or less the same for this shape.

– Vroomfondel
Nov 27 '18 at 8:22












1 Answer
1






active

oldest

votes


















1














Here I have found the length of the object using cv2.minAreaRect() function and calculated the endpoints along the centroid.



The minAreaRect function gives us the center, axes, and angle of the rectangle that encloses the object. I used the angle info to rotate the horizontal vector and generated the endpoints of the line



#Finding the contours in the image
im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

#finding the minimum area rectangle that covers the blob
rect = cv2.minAreaRect(contours[0])
box = cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(img,[box],0,(0,0,255),2)

#Forming the line vector
v = np.matrix([[0], [1]])

#forming the rotation matrix to rotate the line vector
ang = rect[2]* np.pi / 180 #conversion to radians
rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

#Rotating the horizontal vector
rv = rot*v

#half length of the line
lineSize = max(rect[1])*0.5

#extreme points of the line
p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

cv2.line(img, p1, p2, (0,255,0), 2)


Output






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53494893%2fimage-analysis-object-shape-center-and-extrema%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    Here I have found the length of the object using cv2.minAreaRect() function and calculated the endpoints along the centroid.



    The minAreaRect function gives us the center, axes, and angle of the rectangle that encloses the object. I used the angle info to rotate the horizontal vector and generated the endpoints of the line



    #Finding the contours in the image
    im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

    img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

    #finding the minimum area rectangle that covers the blob
    rect = cv2.minAreaRect(contours[0])
    box = cv2.boxPoints(rect)
    box = np.int0(box)
    cv2.drawContours(img,[box],0,(0,0,255),2)

    #Forming the line vector
    v = np.matrix([[0], [1]])

    #forming the rotation matrix to rotate the line vector
    ang = rect[2]* np.pi / 180 #conversion to radians
    rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

    #Rotating the horizontal vector
    rv = rot*v

    #half length of the line
    lineSize = max(rect[1])*0.5

    #extreme points of the line
    p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
    p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

    cv2.line(img, p1, p2, (0,255,0), 2)


    Output






    share|improve this answer




























      1














      Here I have found the length of the object using cv2.minAreaRect() function and calculated the endpoints along the centroid.



      The minAreaRect function gives us the center, axes, and angle of the rectangle that encloses the object. I used the angle info to rotate the horizontal vector and generated the endpoints of the line



      #Finding the contours in the image
      im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

      img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

      #finding the minimum area rectangle that covers the blob
      rect = cv2.minAreaRect(contours[0])
      box = cv2.boxPoints(rect)
      box = np.int0(box)
      cv2.drawContours(img,[box],0,(0,0,255),2)

      #Forming the line vector
      v = np.matrix([[0], [1]])

      #forming the rotation matrix to rotate the line vector
      ang = rect[2]* np.pi / 180 #conversion to radians
      rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

      #Rotating the horizontal vector
      rv = rot*v

      #half length of the line
      lineSize = max(rect[1])*0.5

      #extreme points of the line
      p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
      p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

      cv2.line(img, p1, p2, (0,255,0), 2)


      Output






      share|improve this answer


























        1












        1








        1







        Here I have found the length of the object using cv2.minAreaRect() function and calculated the endpoints along the centroid.



        The minAreaRect function gives us the center, axes, and angle of the rectangle that encloses the object. I used the angle info to rotate the horizontal vector and generated the endpoints of the line



        #Finding the contours in the image
        im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

        #finding the minimum area rectangle that covers the blob
        rect = cv2.minAreaRect(contours[0])
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(img,[box],0,(0,0,255),2)

        #Forming the line vector
        v = np.matrix([[0], [1]])

        #forming the rotation matrix to rotate the line vector
        ang = rect[2]* np.pi / 180 #conversion to radians
        rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

        #Rotating the horizontal vector
        rv = rot*v

        #half length of the line
        lineSize = max(rect[1])*0.5

        #extreme points of the line
        p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
        p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

        cv2.line(img, p1, p2, (0,255,0), 2)


        Output






        share|improve this answer













        Here I have found the length of the object using cv2.minAreaRect() function and calculated the endpoints along the centroid.



        The minAreaRect function gives us the center, axes, and angle of the rectangle that encloses the object. I used the angle info to rotate the horizontal vector and generated the endpoints of the line



        #Finding the contours in the image
        im2, contours, hierarchy = cv2.findContours(img,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

        img = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)

        #finding the minimum area rectangle that covers the blob
        rect = cv2.minAreaRect(contours[0])
        box = cv2.boxPoints(rect)
        box = np.int0(box)
        cv2.drawContours(img,[box],0,(0,0,255),2)

        #Forming the line vector
        v = np.matrix([[0], [1]])

        #forming the rotation matrix to rotate the line vector
        ang = rect[2]* np.pi / 180 #conversion to radians
        rot = np.matrix([[np.cos(ang), -np.sin(ang)],[np.sin(ang), np.cos(ang)]])

        #Rotating the horizontal vector
        rv = rot*v

        #half length of the line
        lineSize = max(rect[1])*0.5

        #extreme points of the line
        p1 = tuple(np.array(rect[0] - lineSize*rv.T)[0].astype(int))
        p2 = tuple(np.array(rect[0] + lineSize*rv.T)[0].astype(int))

        cv2.line(img, p1, p2, (0,255,0), 2)


        Output







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 27 '18 at 11:18









        GopirajGopiraj

        34119




        34119
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53494893%2fimage-analysis-object-shape-center-and-extrema%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Contact image not getting when fetch all contact list from iPhone by CNContact

            count number of partitions of a set with n elements into k subsets

            A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks