Image analysis, object shape, center and extrema
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:
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
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)
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
add a comment |
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:
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
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)
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
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
add a comment |
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:
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
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)
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
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:
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
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)
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
python opencv object-detection
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
add a comment |
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
add a comment |
1 Answer
1
active
oldest
votes
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)
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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)
add a comment |
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)
add a comment |
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)
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)
answered Nov 27 '18 at 11:18
GopirajGopiraj
34119
34119
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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