鱼C论坛

 找回密码
 立即注册
查看: 1423|回复: 2

[已解决]多通道图片阈值分割

[复制链接]
发表于 2023-11-3 18:24:39 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
高光谱多通道图片阈值分割。

发生异常: error
OpenCV(4.7.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:230: error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'
  File "D:\0000可见光2\程序\光谱提取\提取光谱.py", line 38, in <module>
    background_removed_image = cv2.bitwise_and(rawimg_RT, rawimg_RT, mask=binary_mask)
cv2.error: OpenCV(4.7.0) D:\a\opencv-python\opencv-python\opencv\modules\core\src\arithm.cpp:230: error: (-215:Assertion failed) (mtype == CV_8U || mtype == CV_8S) && _mask.sameSize(*psrc1) in function 'cv::binary_op'


输出结果:
(950, 384) (950, 384, 288)
uint8 float32
(950, 384, 288) (950, 384, 288)
uint8 uint8

代码:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import cv2

  4. # Load the hyperspectral image
  5. rawimg_RT = np.fromfile('1-1_RT.raw', dtype=np.float32)
  6. rawimg_RT = rawimg_RT.reshape(950, 384, 288)

  7. # Select a suitable band with maximum contrast between peanuts and background
  8. band_for_masking = 42  # You may need to adjust this based on your data

  9. # Calculate the difference image between peanuts and background
  10. difference_image = rawimg_RT[:,: , band_for_masking]

  11. # Convert the difference image to an 8-bit image
  12. normalized_difference = cv2.normalize(difference_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)

  13. # Apply Otsu's thresholding to create a binary mask
  14. #_, binary_mask = cv2.threshold(normalized_difference, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
  15. _,binary_mask=cv2.threshold(normalized_difference,0.6,1,cv2.THRESH_BINARY)#阈值
  16. print(binary_mask.shape,rawimg_RT.shape)
  17. print(binary_mask.dtype,rawimg_RT.dtype)


  18. cv2.imshow('Background Removed Image', binary_mask)
  19. cv2.waitKey(0)
  20. cv2.destroyAllWindows()


  21. num_channels = 288  # 例如,创建一个3通道的掩膜
  22. binary_mask = np.stack((binary_mask,) * num_channels, axis=2)
  23. rawimg_RT = rawimg_RT.astype(np.uint8)
  24. print(binary_mask.shape,rawimg_RT.shape)
  25. print(binary_mask.dtype,rawimg_RT.dtype)
  26. #binary_mask = np.array(binary_mask, dtype=np.uint8)

  27. # 对高光谱图像应用二值化掩膜
  28. background_removed_image = cv2.bitwise_and(rawimg_RT, rawimg_RT, mask=binary_mask)

  29. # 显示去除背景后的图像
  30. cv2.imshow('Background Removed Image', background_removed_image)
  31. cv2.waitKey(0)
  32. cv2.destroyAllWindows()


复制代码
最佳答案
2023-11-3 18:25:13
根据您提供的代码和错误信息,我注意到问题可能出现在以下几个地方:

1. 数据类型不匹配:根据错误信息,_mask.sameSize(*psrc1)的断言失败,这可能是由于二值化掩膜(binary_mask)的数据类型与原始图像(rawimg_RT)的数据类型不匹配导致的。请确保它们具有相同的数据类型。

   在代码中,您可以尝试将以下行:
  
  1.    rawimg_RT = rawimg_RT.astype(np.uint8)
  2.    
复制代码

2. 通道数不匹配:在创建二值化掩膜后,您将其复制为与原始图像具有相同通道数的形状。但是,根据输出结果,binary_mask的形状为 (950, 384, 1),而 rawimg_RT 的形状为 (950, 384, 288)。由于通道数不匹配,无法使用 cv2.bitwise_and 函数将它们应用于原始图像上。

   您可以尝试重新构建具有相同通道数的二值化掩膜,例如:
  
  1.    num_channels = rawimg_RT.shape[2]
  2.    binary_mask = np.repeat(binary_mask, num_channels, axis=2)
  3.    
复制代码

请参考修改后的代码如下所示:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import cv2
  4. # Load the hyperspectral image
  5. rawimg_RT = np.fromfile('1-1_RT.raw', dtype=np.float32)
  6. rawimg_RT = rawimg_RT.reshape(950, 384, 288)
  7. # Select a suitable band with maximum contrast between peanuts and background
  8. band_for_masking = 42  # You may need to adjust this based on your data
  9. # Calculate the difference image between peanuts and background
  10. difference_image = rawimg_RT[:,:,band_for_masking]
  11. # Convert the difference image to an 8-bit image
  12. normalized_difference = cv2.normalize(difference_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
  13. # Apply Otsu's thresholding to create a binary mask
  14. _, binary_mask = cv2.threshold(normalized_difference, 0.6, 1, cv2.THRESH_BINARY)
  15. cv2.imshow('Binary Mask', binary_mask)
  16. cv2.waitKey(0)
  17. cv2.destroyAllWindows()
  18. # Match the number of channels in the binary mask to the original image
  19. num_channels = rawimg_RT.shape[2]
  20. binary_mask = np.repeat(binary_mask, num_channels, axis=2)
  21. # Convert data types to match
  22. rawimg_RT = rawimg_RT.astype(np.uint8)
  23. binary_mask = binary_mask.astype(np.uint8)
  24. # Apply binary mask to the hyperspectral image
  25. background_removed_image = cv2.bitwise_and(rawimg_RT, rawimg_RT, mask=binary_mask)
  26. cv2.imshow('Background Removed Image', background_removed_image)
  27. cv2.waitKey(0)
  28. cv2.destroyAllWindows()
复制代码

请尝试使用修改后的代码,并确保 1-1_RT.raw 文件存在于脚本所在的目录中。如果问题仍然存在,请提供更多关于错误的详细信息,以便我们进一步排查。

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2023-11-3 18:25:13 | 显示全部楼层    本楼为最佳答案   
根据您提供的代码和错误信息,我注意到问题可能出现在以下几个地方:

1. 数据类型不匹配:根据错误信息,_mask.sameSize(*psrc1)的断言失败,这可能是由于二值化掩膜(binary_mask)的数据类型与原始图像(rawimg_RT)的数据类型不匹配导致的。请确保它们具有相同的数据类型。

   在代码中,您可以尝试将以下行:
  
  1.    rawimg_RT = rawimg_RT.astype(np.uint8)
  2.    
复制代码

2. 通道数不匹配:在创建二值化掩膜后,您将其复制为与原始图像具有相同通道数的形状。但是,根据输出结果,binary_mask的形状为 (950, 384, 1),而 rawimg_RT 的形状为 (950, 384, 288)。由于通道数不匹配,无法使用 cv2.bitwise_and 函数将它们应用于原始图像上。

   您可以尝试重新构建具有相同通道数的二值化掩膜,例如:
  
  1.    num_channels = rawimg_RT.shape[2]
  2.    binary_mask = np.repeat(binary_mask, num_channels, axis=2)
  3.    
复制代码

请参考修改后的代码如下所示:
  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import cv2
  4. # Load the hyperspectral image
  5. rawimg_RT = np.fromfile('1-1_RT.raw', dtype=np.float32)
  6. rawimg_RT = rawimg_RT.reshape(950, 384, 288)
  7. # Select a suitable band with maximum contrast between peanuts and background
  8. band_for_masking = 42  # You may need to adjust this based on your data
  9. # Calculate the difference image between peanuts and background
  10. difference_image = rawimg_RT[:,:,band_for_masking]
  11. # Convert the difference image to an 8-bit image
  12. normalized_difference = cv2.normalize(difference_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)
  13. # Apply Otsu's thresholding to create a binary mask
  14. _, binary_mask = cv2.threshold(normalized_difference, 0.6, 1, cv2.THRESH_BINARY)
  15. cv2.imshow('Binary Mask', binary_mask)
  16. cv2.waitKey(0)
  17. cv2.destroyAllWindows()
  18. # Match the number of channels in the binary mask to the original image
  19. num_channels = rawimg_RT.shape[2]
  20. binary_mask = np.repeat(binary_mask, num_channels, axis=2)
  21. # Convert data types to match
  22. rawimg_RT = rawimg_RT.astype(np.uint8)
  23. binary_mask = binary_mask.astype(np.uint8)
  24. # Apply binary mask to the hyperspectral image
  25. background_removed_image = cv2.bitwise_and(rawimg_RT, rawimg_RT, mask=binary_mask)
  26. cv2.imshow('Background Removed Image', background_removed_image)
  27. cv2.waitKey(0)
  28. cv2.destroyAllWindows()
复制代码

请尝试使用修改后的代码,并确保 1-1_RT.raw 文件存在于脚本所在的目录中。如果问题仍然存在,请提供更多关于错误的详细信息,以便我们进一步排查。

球一个最佳答案谢谢啦!这对我非常重要!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-11-3 18:26:11 | 显示全部楼层
在代码中,出现了OpenCV的错误信息:Assertion failed,这是由于在进行二值化掩膜操作时出现了类型不匹配的错误。

错误的原因是在进行二值化操作时, normalized_difference  是一个  uint8  类型的图像,而  binary_mask  是一个  float32  类型的图像,这导致了类型不匹配的错误。

要解决这个问题,我们需要将  binary_mask  的数据类型转换为  uint8 ,以与  normalized_difference  的数据类型匹配。

在代码中,已经使用了  astype  函数将  rawimg_RT  的数据类型转换为  uint8 ,我们可以使用同样的方法将  binary_mask  的数据类型转换为  uint8 。

将  binary_mask = np.array(binary_mask, dtype=np.uint8)  这行代码取消注释,并将其修改为  binary_mask = binary_mask.astype(np.uint8) 。

修改后的代码如下:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. import cv2

  4. # Load the hyperspectral image
  5. rawimg_RT = np.fromfile('1-1_RT.raw', dtype=np.float32)
  6. rawimg_RT = rawimg_RT.reshape(950, 384, 288)

  7. # Select a suitable band with maximum contrast between peanuts and background
  8. band_for_masking = 42  # You may need to adjust this based on your data

  9. # Calculate the difference image between peanuts and background
  10. difference_image = rawimg_RT[:,:, band_for_masking]

  11. # Convert the difference image to an 8-bit image
  12. normalized_difference = cv2.normalize(difference_image, None, 0, 255, cv2.NORM_MINMAX, cv2.CV_8U)

  13. # Apply Otsu's thresholding to create a binary mask
  14. #_, binary_mask = cv2.threshold(normalized_difference, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
  15. _,binary_mask=cv2.threshold(normalized_difference,0.6,1,cv2.THRESH_BINARY)#阈值
  16. print(binary_mask.shape,rawimg_RT.shape)
  17. print(binary_mask.dtype,rawimg_RT.dtype)

  18. cv2.imshow('Background Removed Image', binary_mask)
  19. cv2.waitKey(0)
  20. cv2.destroyAllWindows()

  21. num_channels = 288  # 例如,创建一个3通道的掩膜
  22. binary_mask = np.stack((binary_mask,) * num_channels, axis=2)
  23. rawimg_RT = rawimg_RT.astype(np.uint8)
  24. binary_mask = binary_mask.astype(np.uint8)

  25. # 对高光谱图像应用二值化掩膜
  26. background_removed_image = cv2.bitwise_and(rawimg_RT, rawimg_RT, mask=binary_mask)

  27. # 显示去除背景后的图像
  28. cv2.imshow('Background Removed Image', background_removed_image)
  29. cv2.waitKey(0)
  30. cv2.destroyAllWindows()
复制代码


这样修改后,类型不匹配的错误应该就会解决了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-4-23 00:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表