Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-如何根据图像的值裁剪图像?_Python_Image_Numpy_Opencv_Matrix - Fatal编程技术网

Python-如何根据图像的值裁剪图像?

Python-如何根据图像的值裁剪图像?,python,image,numpy,opencv,matrix,Python,Image,Numpy,Opencv,Matrix,我有一个这样的图像:所有的零像素;具有一些非零值的正方形。我想裁剪图像,以便创建一个只有非零值的新图像。我尝试过类似于image=np.extract(image!=0,image)或image=image[image!=0]的方法,但这些方法返回的是数组,而不是矩阵。 我怎样才能解决这个问题? 谢谢 一种方法是使用and: 使用示例数组: image = np.array([[0,0,0,0,0], [0,0,1,2,0], [0,0,3,3,0], [0,0,0,0,0], [0,0,0,0

我有一个这样的图像:所有的零像素;具有一些非零值的正方形。我想裁剪图像,以便创建一个只有非零值的新图像。我尝试过类似于
image=np.extract(image!=0,image)
image=image[image!=0]
的方法,但这些方法返回的是数组,而不是矩阵。 我怎样才能解决这个问题? 谢谢

一种方法是使用and:

使用示例数组:

image = np.array([[0,0,0,0,0], [0,0,1,2,0], [0,0,3,3,0], [0,0,0,0,0], [0,0,0,0,0]])

print(image)

array([[0, 0, 0, 0, 0],
       [0, 0, 1, 2, 0],
       [0, 0, 3, 3, 0],
       [0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0]])

x, y = np.nonzero(image)
xl,xr = x.min(),x.max()
yl,yr = y.min(),y.max()
image[xl:xr+1, yl:yr+1]

array([[1, 2],
       [3, 3]])

作为@yatu解决方案的替代方案,您可以使用它来索引所传递数组的叉积:

import numpy as np
image = np.array([[0,0,0,0,0], [0,0,1,2,0], [0,0,3,3,0], [0,0,0,0,0], [0,0,0,0,0]])

x, y = np.nonzero(image)
image[np.ix_(np.unique(x),np.unique(y))]
array([[1, 2],
       [3, 3]])
在哪里

np.ix_(np.unique(x),np.unique(y))
(array([[1],
        [2]], dtype=int64), array([[2, 3]], dtype=int64))
如果不想使用numpy
np.nonzero
,可以使用

也> <代码> CV.Engulink Rec> <代码>比NUMPY快(可能是因为C++绑定)?< /P> 时机 在上面的示例中,使用5x5数组时,

cv.boundingRect
的速度要快2倍:

%timeit x, y = np.nonzero(image)
1.4 µs ± 219 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit x, y, w, h = cv.boundingRect(image)
722 ns ± 30.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
对于1000x1500图像,
cv.boundingRect
的速度要快得多(40倍到2000倍,取决于图像的内容):


如果只处理一个图像,Numpy仍然足够快。例如,在处理实时视频帧时,情况会有所不同。

一旦提取了最小值和最大值,就可以按照
图像[x.min():x.max()+1,y.min():y.max()+1]进行切片。
来获取子矩阵,而不是使用重塑。
cv.boundingRect
也可以这样做,而且速度更快
image = np.array([[0,0,0,0,0], [0,0,1,2,0], [0,0,3,3,0], [0,0,0,0,0], [0,0,0,0,0]])

# the line below is usually not necessary when dealing with
# gray scale images opened with imread(), but you need it if 
# you're working with the array created above, to get uint8 values
image = cv.convertScaleAbs(image)

x, y, w, h = cv.boundingRect(image)
newImg = image[y:y+h, x:x+w]
%timeit x, y = np.nonzero(image)
1.4 µs ± 219 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

%timeit x, y, w, h = cv.boundingRect(image)
722 ns ± 30.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
# blank (all zero) image 
image = np.zeros((1500,1000), dtype=np.uint8)

%timeit x, y = np.nonzero(image)
6.67 ms ± 40 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x, y, w, h = cv.boundingRect(image)
159 µs ± 1.14 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# only non-zero pixels
image = np.ones((1500,1000), dtype=np.uint8)

%timeit x, y = np.nonzero(image)
17.2 ms ± 155 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit x, y, w, h = cv.boundingRect(image)
7.48 µs ± 46.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)