如何解决如何使用 OpenCV 计算类似 skimage 的图像直方图?
在之前创建的代码中,直方图是使用 skimage
模块计算的,方法如下:
h = skimage.exposure.histogram(img,nbins=256)
但是,现在由于某些原因,我不能使用 skimage
而只能使用 OpenCV。
所以,当我尝试
h = cv2.calcHist(img,[0],None,[256],[0,256])
OpenCV 的 h
和 skimage
的 h
的输出不同,此后的代码中断。
那么,我该怎么做才能使 OpenCV 的直方图输出与以前相同?
示例图片:
(请点击图片看清楚,只是绿色加噪点。)
然后我将其转换为 black-and-white
使用:
img = cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
img = img/255 #to convert values from [0,255] to [0,1]
img = img[:,:,0]
skimage
的直方图:
(array([ 4,3,15,23,49,94,152,183,207,200,187,165,141,78,58,39,8,4,1,1],dtype=int64),array([0.08249847,0.08278952,0.08308058,0.08337163,0.08366268,0.08395374,0.08424479,0.08453585,0.0848269,0.08511795,0.08540901,0.08570006,0.08599112,0.08628217,0.08657322,0.08686428,0.08715533,0.08744638,0.08773744,0.08802849,0.08831955,0.0886106,0.08890165,0.08919271,0.08948376,0.08977482,0.09006587,0.09035692,0.09064798,0.09093903,0.09123009,0.09152114,0.09181219,0.09210325,0.0923943,0.09268536,0.09297641,0.09326746,0.09355852,0.09384957,0.09414063,0.09443168,0.09472273,0.09501379,0.09530484,0.09559589,0.09588695,0.096178,0.09646906,0.09676011,0.09705116,0.09734222,0.09763327,0.09792433,0.09821538,0.09850643,0.09879749,0.09908854,0.0993796,0.09967065,0.0999617,0.10025276,0.10054381,0.10083487,0.10112592,0.10141697,0.10170803,0.10199908,0.10229013,0.10258119,0.10287224,0.1031633,0.10345435,0.1037454,0.10403646,0.10432751,0.10461857,0.10490962,0.10520067,0.10549173,0.10578278,0.10607384,0.10636489,0.10665594,0.106947,0.10723805,0.10752911,0.10782016,0.10811121,0.10840227,0.10869332,0.10898437,0.10927543,0.10956648,0.10985754,0.11014859,0.11043964,0.1107307,0.11102175,0.11131281,0.11160386,0.11189491,0.11218597,0.11247702,0.11276808,0.11305913,0.11335018,0.11364124,0.11393229,0.11422335,0.1145144,0.11480545,0.11509651,0.11538756,0.11567862,0.11596967,0.11626072,0.11655178,0.11684283,0.11713388,0.11742494,0.11771599,0.11800705,0.1182981,0.11858915,0.11888021,0.11917126,0.11946232,0.11975337,0.12004442,0.12033548,0.12062653,0.12091759,0.12120864,0.12149969,0.12179075,0.1220818,0.12237286,0.12266391,0.12295496,0.12324602,0.12353707,0.12382812,0.12411918,0.12441023,0.12470129,0.12499234,0.12528339,0.12557445,0.1258655,0.12615656,0.12644761,0.12673866,0.12702972,0.12732077,0.12761183,0.12790288,0.12819393,0.12848499,0.12877604,0.1290671,0.12935815,0.1296492,0.12994026,0.13023131,0.13052237,0.13081342,0.13110447,0.13139553,0.13168658,0.13197763,0.13226869,0.13255974,0.1328508,0.13314185,0.1334329,0.13372396,0.13401501,0.13430607,0.13459712,0.13488817,0.13517923,0.13547028,0.13576134,0.13605239,0.13634344,0.1366345,0.13692555,0.13721661,0.13750766,0.13779871,0.13808977,0.13838082,0.13867188,0.13896293,0.13925398,0.13954504,0.13983609,0.14012714,0.1404182,0.14070925,0.14100031,0.14129136,0.14158241,0.14187347,0.14216452,0.14245558,0.14274663,0.14303768,0.14332874,0.14361979,0.14391085,0.1442019,0.14449295,0.14478401,0.14507506,0.14536612,0.14565717,0.14594822,0.14623928,0.14653033,0.14682138,0.14711244,0.14740349,0.14769455,0.1479856,0.14827665,0.14856771,0.14885876,0.14914982,0.14944087,0.14973192,0.15002298,0.15031403,0.15060509,0.15089614,0.15118719,0.15147825,0.1517693,0.15206036,0.15235141,0.15264246,0.15293352,0.15322457,0.15351562,0.15380668,0.15409773,0.15438879,0.15467984,0.15497089,0.15526195,0.155553,0.15584406,0.15613511,0.15642616,0.15671722]))
OpenCV
的直方图:
array([[ 0.],[ 0.],[ 1.],[ 2.],[ 7.],[ 8.],[13.],[12.],[20.],[17.],[ 5.],[ 4.],[10.],[ 3.],[18.],[11.],[39.],[44.],[23.],[26.],[ 0.]],dtype=float32)
解决方法
恐怕这里出了很多问题。为了重建您的结果,我使用了这段代码:
import cv2
import skimage.exposure
# Read image as-is
img = cv2.imread('TjFAo.png')
# Histogram OpenCV - incorrect usage
h_ocv = cv2.calcHist(img,[0],None,[256],[0,256])
print(h_ocv.T)
# [[ 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 2. 0. 7. 8. 13. 12. 20. 20.
# 17. 5. 8. 4. 10. 3. 20. 2. 18. 11. 39. 12. 44. 13. 23. 8. 26. 8.
# ...
# Some image manipulation - why? whatfor?
img = cv2.cvtColor(img,cv2.COLOR_BGR2YUV)
img = img / 255
img = img[:,:,0]
# Histogram skimage
h_ski = skimage.exposure.histogram(img,nbins=256)
print(h_ski[0])
# [ 4 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0
# 0 0 0 0 0 0 0 0 15 0 0 0 0 0 0 0 0 0
# ...
- 您在原始图像的蓝色通道上计算 OpenCV 直方图。或者,准确地说,您实际上并没有这样做,因为这里的用法不正确。您也需要将
img
放在括号中。 - 您将图像转换为 YUV 颜色空间,然后将第一个通道用于
skimage
直方图。为什么?你在这里有什么想法? - 您无需在此处为
[0.0 ... 1.0]
强制执行skimage
范围内的值。
来看看正确的用法,先来看看原图的蓝色通道:
import cv2
import skimage.exposure
# Read image as-is
img = cv2.imread('TjFAo.png')
# Histogram OpenCV - brackets around the image!
h_ocv = cv2.calcHist([img],256])
print(h_ocv.T)
# [[ 0. 0. 0. 0. 0. 0. 0. 0. 1. 2. 9. 10. 27. 62.
# 107. 154. 174. 208. 213. 193. 166. 134. 73. 52. 20. 4. 1. 1.
# ...
# Histogram skimage - set source_range!
h_ski = skimage.exposure.histogram(img[...,0],nbins=256,source_range='dtype')
print(h_ski[0])
# [ 0 0 0 0 0 0 0 0 1 2 9 10 27 62 107 154 174 208
# 213 193 166 134 73 52 20 4 1 1 1 0 0 0 0 0 0 0
# ...
如果你真的想要灰度图像的直方图,首先转换图像:
import cv2
import skimage.exposure
# Read image as-is
img = cv2.imread('TjFAo.png')
# Convert to grayscale
img = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Histogram OpenCV - brackets around the image!
h_ocv = cv2.calcHist([img],256])
print(h_ocv.T)
# [[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
# 0. 0. 0. 0. 0. 0. 0. 4. 3. 15. 23. 49. 94. 152.
# ...
# Histogram skimage - set source_range!
h_ski = skimage.exposure.histogram(img,source_range='dtype')
print(h_ski[0])
# [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
# 0 0 0 4 3 15 23 49 94 152 183 207 200 187 165 141 78 58
# ...
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.9.1
PyCharm: 2021.1.1
OpenCV: 4.5.1
scikit-image: 0.18.1
----------------------------------------
,
请注意,skimage.exposure.histogram(img,nbins=256)
返回一个包含两个数组的元组,第一个是给定 img
中该特定值的像素总数,第二个数组归一化为 {{1} }.
所以,如果你只想找到给定值的像素总数,那么你可以使用这个:
1
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。