Reputation: 7343
I'm trying to run some Convex Hull image processing. Basically what I want to do is to close off an open contour.
I found this answer over at the opencv forum and it's exactly what I wanted to do. I started converting the code from C++ to Python some time ago. I succeeded with converting the code of the question, but the code for the answer is giving me a tougher time than expected.
This is what I have so far:
import cv2
import numpy as np
def contoursConvexHull(contours):
print("contours length = ", len(contours))
print("contours length of first item = ", len(contours[1]))
pts = []
for i in range(0, len(contours)):
for j in range(0, len(contours[i])):
pts.append(contours[i][j])
result = cv2.convexHull(pts)
return result
# Get our image in color mode (1)
src = cv2.imread("source.png", 1);
# Convert the color from BGR to Gray
srcGray = cv2.cvtColor(src, cv2.COLOR_BGR2GRAY)
# Use Gaussian Blur
srcBlur = cv2.GaussianBlur(srcGray, (3, 3), 0)
# ret is the returned value, otsu is an image
ret, otsu = cv2.threshold(srcBlur, 0, 255,
cv2.THRESH_BINARY+cv2.THRESH_OTSU)
# Use canny
srcCanny = cv2.Canny(srcBlur, ret, ret*2, 3)
# im is the output image
# contours is the contour list
# I forgot what heirarchy was
im, contours, heirarchy = cv2.findContours(srcCanny,
cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(src, contours, -1, (0, 255, 0), 3)
ConvexHullPoints = contoursConvexHull(contours)
cv2.polylines(src, [ConvexHullPoints], True, (0, 255, 255), 2)
cv2.imshow("Test", src)
cv2.waitKey(0)
And when I'm trying to run it, it's giving me
result = cv2.convexHull(pts)
TypeError: points is not a numpy array, neither a scalar
And I'm guessing that I'm feeding the convexHull
an input and it wants something else.
I'm pretty decent at C++ but I'm a total beginner at Python. I think I may be doing something wrong with I'm appending the contour elements to the pts
list?
And honestly, I'm not all too sure why we need to append the points back to a new array, there doesn't seem to be any value manipulation or rearrangement that's going on.
Here's the C++ code for reference:
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <stdlib.h>
#include <stdio.h>
using namespace cv;
using namespace std;
vector<Point> contoursConvexHull( vector<vector<Point> > contours )
{
vector<Point> result;
vector<Point> pts;
for ( size_t i = 0; i< contours.size(); i++)
for ( size_t j = 0; j< contours[i].size(); j++)
pts.push_back(contours[i][j]);
convexHull( pts, result );
return result;
}
int main( int, char** argv )
{
Mat src, srcGray,srcBlur,srcCanny;
src = imread( argv[1], 1 );
cvtColor(src, srcGray, CV_BGR2GRAY);
blur(srcGray, srcBlur, Size(3, 3));
Canny(srcBlur, srcCanny, 0, 100, 3, true);
vector<vector<Point> > contours;
findContours( srcCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE );
Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);
for (int i = 0; i< contours.size(); i++)
{
Scalar color = Scalar( 255,255,255);
drawContours( drawing, contours, i, color, 2 );
}
vector<Point> ConvexHullPoints = contoursConvexHull(contours);
polylines( drawing, ConvexHullPoints, true, Scalar(0,0,255), 2 );
imshow("Contours", drawing);
polylines( src, ConvexHullPoints, true, Scalar(0,0,255), 2 );
imshow("contoursConvexHull", src);
waitKey();
return 0;
}
Upvotes: 0
Views: 2040
Reputation: 8078
The error say that pts
is not an numpy array; its a python list
.
To convert pts
to an array, import numpy and do the simple conversion:
import numpy as np
# code ....
pts = np.array(pts)
result = cv2.convexHull(pts)
Upvotes: 1