简体   繁体   English

在python中使用opencv库对图像进行阈值处理,并使用for循环使用不同的标志

[英]Thresholding image using opencv library in python with different flags using for loop

I imported cv2 as cv, created a list of threshold flags, concatenated 'cv.'我将 cv2 作为 cv 导入,创建了一个阈值标志列表,并连接了“cv”。 with the flags and then created a for loop for passing the flags as arguments.使用标志,然后创建一个 for 循环来将标志作为参数传递。 But python shows TypeError.但是python显示TypeError。 I have attached the image of the output.我附上了输出的图像。 Kindly help me create all the possible thresholds using a loop or some other way except for explicitly mentioning the flags every time.请帮助我使用循环或其他方式创建所有可能的阈值,除了每次明确提及标志。

[ [代码的输出 - Jupyter ] ]

In OpenCV, the given threshold options (eg cv.THRESH_BINARY or cv.THRESH_BINARY_INV) are actually constant integer values.在 OpenCV 中,给定的阈值选项(例如 cv.THRESH_BINARY 或 cv.THRESH_BINARY_INV)实际上是常量整数值。 You are trying to use strings instead of these integer values.您正在尝试使用字符串而不是这些整数值。 That is the reason why you get the Type Error.这就是您收到类型错误的原因。 If you want to apply all these different thresholds in a loop, one option is to create a different list for these options, like this:如果您想在循环中应用所有这些不同的阈值,一种选择是为这些选项创建不同的列表,如下所示:

threshold_options = [cv.THRESH_BINARY, cv.THRESH_BINARY_INV, ...]

That way, you can then use the values of this list in the loop as follows:这样,您就可以在循环中使用此列表的值,如下所示:

retval, thresh = cv.threshold(img, 127, 255, threshold_options[i])

The entire code would be as follows:整个代码如下:

titles = [ 'THRESH_BINARY',
'THRESH_BINARY_INV',
'THRESH_MASK',
'THRESH_OTSU',
'THRESH_TOZERO',
'THRESH_TOZERO_INV',
'THRESH_TRIANGLE',
'THRESH_TRUNC']

threshold_options = [ cv.THRESH_BINARY,
cv.THRESH_BINARY_INV,
cv.THRESH_MASK,
cv.THRESH_OTSU,
cv.THRESH_TOZERO,
cv.THRESH_TOZERO_INV,
cv.THRESH_TRIANGLE,
cv.THRESH_TRUNC]


for i in range(len(titles)):
    retval, thresh = cv.threshold(img, 127, 255, threshold_options[i])
    plt.subplot(2,3,i+1), plt.title(titles[i]), plt.imshow(thresh, 'gray')
plt.show()

This might be related: OpenCV Thresholding example这可能是相关的: OpenCV 阈值示例

First off, there is no need to use range , you can simply do for flag in titles: and pass flag .首先,不需要使用range ,您可以简单地for flag in titles:执行for flag in titles:并传递flag Have you checked if your image is loaded correctly?您是否检查过您的图像是否正确加载? Are you sure that your flag is repsonsible for your error?您确定您的标志对您的错误负责吗?

For future posts, please include a minimal reproducible example.对于以后的帖子,请包含一个最小的可重复示例。

You code is not working because the type of the flags is int and not string .您的代码不起作用,因为标志的类型是int而不是string

You can print the type: print(type(cv.THRESH_BINARY)) .您可以打印类型: print(type(cv.THRESH_BINARY))
The result is <class 'int'> .结果是<class 'int'>

You may create a list of int s:您可以创建一个int列表:

th_flags = [cv.THRESH_BINARY, cv.THRESH_BINARY_INV, cv.THRESH_TRUNC, cv.THRESH_TOZERO, cv.THRESH_TOZERO_INV]

for th in th_flags:
    retval, thresh = cv.threshold(img, 127, 255, th)
    cv.imshow('thresh', thresh)
    cv.waitKey(1000)

cv.destroyAllWindows()

The code doesn't cover all the possible options .该代码并未涵盖所有可能的选项
Few flags can be combined using summation.很少有标志可以使用求和来组合。

Example:例子:

_, thresh = cv.threshold(img, 127, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM