python VTK(十) ----直方图统计

灰色图像直方图统计

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import vtk
from vtk.util.numpy_support import vtk_to_numpy
reader = vtk.vtkJPEGReader()   # 读入灰度图
reader.SetFileName(r'E:\lena-gray.jpg')
reader.Update()

bins = 16  # 表示图像灰度直方图的间隔数目, 也可以理解为直方图一维数组的维数。
comps = 1

histogram = vtk.vtkImageAccumulate()
histogram.SetInputData(reader.GetOutput())
histogram.SetComponentExtent(0, bins-1, 0, 0, 0, 0)
'''
计算每个组份的直方图的最小值和最大值.vtkImageAccumulate 最大支持像素值分为三个组分的直方图,共有六个参数,
分别表示每个组分的最小值和最大值。该例中由于计算的是灰度图像直方图,只有一个组分,因此第二组分和第三组分都设为0;
而第一组分直方图维数为bins=16,那么其灰度范围是[0, bins-1]
'''
histogram.SetComponentOrigin(0, 0, 0)
'''
统计每个组分直方图时的起始灰度值,这里设置为0,表示从0开始统计直方图。由于vtkImageAccumulate
最大支持像素值为三个组分,因此这里也要设置三个参数。如果图像的灰度范围为[1000, 2000],
那么计算直方图时,其起始灰度值应该设置为1000。
'''
histogram.SetComponentSpacing(256/bins, 0, 0)
'''
设置直方图每个间隔代表的灰度范围,例如当一个图像灰度范围为[1000, 2000], 统计直方图的间隔数bins为100时,
对应的space应该设置为(100, 0, 0)
'''
histogram.Update()
# 注意此处输出的直方图图像的数据类型为int
output = vtk_to_numpy(histogram.GetOutput().GetPointData().GetScalars())
frequencies = vtk.vtkIntArray()
frequencies.SetNumberOfComponents(1)

for j in range(bins):
    frequencies.InsertNextTuple([output[j]])

dataObject = vtk.vtkDataObject()
dataObject.GetFieldData().AddArray(frequencies)

barChart = vtk.vtkBarChartActor()
'''
vtkBarChartActor用来显示条形图,可以利用它显示直方图,但是它接收的数据类型为 vtkDataObject 类型,因此需要先对
直方图数据进行类型转换:先将直方图数据存储到vtkIntArray数组frequencies中,然后通过GetFieldData函数
AddArray(frequencies)将其添加到vtkDataObject对象中。
'''
barChart.SetInput(dataObject)
barChart.SetTitle('Histogram')
barChart.GetPositionCoordinate().SetValue(0.05, 0.05, 0.0)   # 设置的是窗口中显示图表的所在矩形的左下角点和右上角点坐标
barChart.GetPosition2Coordinate().SetValue(0.95, 0.95, 0.0)
barChart.GetProperty().SetColor(0, 0, 0)
barChart.GetTitleTextProperty().SetColor(0, 0, 0)
barChart.GetLabelTextProperty().SetColor(0, 0, 0)
barChart.GetLegendActor().SetNumberOfEntries(dataObject.GetFieldData().GetArray(0).GetNumberOfTuples())
barChart.LegendVisibilityOff()
barChart.LabelVisibilityOff()

colors = [[1, 0, 0],
          [0, 1, 0],
          [0, 0, 1]]

count = 0
for i in range(bins):
    for j in range(comps):
        count += 1
        barChart.SetBarColor(count, colors[j])

renderer = vtk.vtkRenderer()
renderer.AddActor(barChart)
renderer.SetBackground(1.0, 1.0, 1.0)

renderWindow =vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.SetSize(640, 480)
renderWindow.Render()
renderWindow.SetWindowName('ImageAccumulateExample')

renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.Initialize()
renderWindowInteractor.Start()

python VTK(十) ----直方图统计_第1张图片
python VTK(十) ----直方图统计_第2张图片

彩色图像灰度图统计

#!/usr/bin/env python 
# -*- coding:utf-8 -*-
import vtk
reader = vtk.vtkBMPReader()
reader.SetFileName(r'E:/lena.bmp')
reader.Update()
'''
彩色图像有三个颜色通道,因此需要提取RGB三个通道数据分别计算直方图
'''
numComponents = reader.GetOutput().GetNumberOfScalarComponents()
plot = vtk.vtkXYPlotActor()
'''
灰度直方图使用vtkBarChartActor柱状图来显示直方图,在这使用vtkXYPlotActor。
vtkXYPlotActor可以用来显示而为曲线,它可以接收多个输入数据,本例中输入了三条曲线,分别是红绿蓝,

'''
plot.ExchangeAxesOff()
plot.SetLabelFormat('%g')
plot.SetXTitle('Intensity')
plot.SetYTitle('Frequency')
plot.SetXValuesToValue()
plot.GetProperty().SetColor(0.0, 0.0, 0.0)
plot.GetAxisLabelTextProperty().SetColor(0.0, 0.0, 0.0)
plot.GetAxisTitleTextProperty().SetColor(0.0, 0.0, 0.0)

colors = [[1, 0, 0],
          [0, 1, 0],
          [0, 0, 1]]

labels = ['Red', 'Green', 'Blue']

xmax = 0
ymax = 0

for i in range(numComponents):
    extract = vtk.vtkImageExtractComponents()   # 提取每个组分图像
    extract.SetInputConnection(reader.GetOutputPort())
    extract.SetComponents(i)
    extract.Update()

    range = extract.GetOutput().GetScalarRange()
    extent = int(range[1] - range[0]-1)

    histogram = vtk.vtkImageAccumulate()   # 统计每个组分的直方图
    histogram.SetInputConnection(extract.GetOutputPort())
    histogram.SetComponentExtent(0, extent, 0, 0, 0, 0)
    histogram.SetComponentOrigin(range[0], 0, 0)
    histogram.SetComponentSpacing(1, 0, 0)   # 每个灰度计算统计一个频率,而且灰度起点为图像的最小灰度值
    histogram.SetIgnoreZero(1)  # 像素值为0的像素不进行统计
    histogram.Update()

    if range[1] > xmax:
        xmax = range[1]
    if histogram.GetOutput().GetScalarRange()[1] > ymax:
        ymax = histogram.GetOutput().GetScalarRange()[1]

    plot.AddDataSetInput(histogram.GetOutput())   # 注意新版vtk需使用AddDataSetInput
    plot.SetPlotColor(i, colors[i])
    plot.SetPlotLabel(i, labels[i])
    plot.LegendOn()

plot.SetXRange(0, xmax)   # 设定X轴的数据范围
plot.SetYRange(0, ymax)   # 设定Y轴的数据范围

renderer = vtk.vtkRenderer()
renderer.AddActor(plot)
renderer.SetBackground(1.0, 1.0, 1.0)

renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindow.SetSize(640, 480)
renderWindow.Render()
renderWindow.SetWindowName('ImageAccumulateExample2')

renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
renderWindowInteractor.Initialize()
renderWindowInteractor.Start()

python VTK(十) ----直方图统计_第3张图片
python VTK(十) ----直方图统计_第4张图片

你可能感兴趣的:(python,计算机视觉,vtk,图像处理,人工智能)