Python OpenCV - ConvexHull 错误“点不是 numpy 数组,也不是标量”?

Posted

技术标签:

【中文标题】Python OpenCV - ConvexHull 错误“点不是 numpy 数组,也不是标量”?【英文标题】:Python OpenCV - ConvexHull error "Points is not a numpy array, neither a scalar"? 【发布时间】:2017-03-09 14:59:12 【问题描述】:

我正在尝试运行一些 Convex Hull 图像处理。基本上我想要做的是关闭一个开放的轮廓。

我找到了this answer over at the opencv forum,这正是我想做的。前段时间我开始将代码从 C++ 转换为 Python。我成功地转换了问题的代码,但答案的代码给了我比预期更艰难的时间。

这是我目前所拥有的:

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)

当我尝试运行它时,它给了我

    result = cv2.convexHull(pts)
TypeError: points is not a numpy array, neither a scalar

我猜我正在给convexHull 输入一个输入,它想要别的东西。

我在 C++ 方面相当不错,但我是 Python 的初学者。我想我将轮廓元素附加到pts 列表中可能做错了什么?

老实说,我不太清楚为什么我们需要将点附加回一个新数组,似乎没有任何值操作或重新排列正在发生。

以下是 C++ 代码供参考:

#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;

【问题讨论】:

【参考方案1】:

错误说pts不是一个numpy数组;它是一条蟒蛇list

要将pts 转换为数组,请导入 numpy 并进行简单的转换:

import numpy as np

# code ....

pts = np.array(pts)
result = cv2.convexHull(pts)

【讨论】:

这可以使代码运行。但是,我仍然没有得到预期的结果。 这比较棘手,但希望我回答了你原来的问题。您可以更新您的问题以反映新问题。事实上,可以考虑提出一个新问题。 我明白了,我只需要用方括号将ConvexHullPoints 括起来,代码就可以按预期工作了。

以上是关于Python OpenCV - ConvexHull 错误“点不是 numpy 数组,也不是标量”?的主要内容,如果未能解决你的问题,请参考以下文章

Python-OpenCV学习:OpenCV结构

如何在mac上安装opencv与python

OpenCV training program, part 2: OpenCV-Python Tutorials

opencv-python

Opencv+Python:在Opencv中绘制函数

OpenCV-Python实战(19)——OpenCV与深度学习的碰撞