医疗影像的图像处理基础

https://blog.csdn.net/myboyliu2007/article/details/85112421

医疗影像的图像处理基础
介绍
In this first assignment, we are going to implement and apply some basic image processing techniques, and we will get familiar with some kind of medical imaging data.
In particular, we will be working with data from:

在第一个任务中,我们将实现并应用一些基本的图像处理技术,以此来熟悉一些医学影像数据。
特别是我们将使用以下数据:

mammography (breast, 2D)
histopathology (colon, 2D)
chest CT (lungs, 3D)
We will implement the following techniques:

conversion of raw mammography data into a gray-scale image
stain normalization in digital pathology with histogram matching
trachea detection in chest CT with blob detection
将实现下面的技术:

将原始的乳腺X片数据转为灰度图片
用直方图匹配对病历切片图像归一化
Libraries
First, we import the basic libraries necessary to develop this assignment. Feel free to include more libraries if needed.

import requests
import zipfile
from tqdm import tnrange, tqdm_notebook
import os
import SimpleITK as sitk
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
%matplotlib inline 
import numpy as np
from PIL import Image
import dicom
from IPython import display
import time
from mpl_toolkits.mplot3d import Axes3D
import copy
matplotlib.rcParams['figure.figsize'] = (20, 17)
import scipy.signal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
乳腺X光片灰度图变换
The first assignment consists in reconstructing a gray-scale mammography image from the raw data acquired with the mammography machine. As we have seen in the lecture, there are several steps that have to be applied to reconstruct a gray-scale image that can actually be read by radiologists with the aim of detecting tumors, masses, cysts, micro-calcifications.

第一项任务包括从乳腺X光片机获取的原始数据,重建灰度乳腺X光图像。 必须采用几个步骤来重建灰度图像,从而使得放射科医生可以阅读这些图像,目的是检测肿瘤,肿块,囊肿,微钙化。

Read image
# raw and gray-level data in ITK format
raw_img_filename = './assignment_1/raw_mammography.mhd'
out_img_filename = './assignment_1/processed_mammography.mhd'

# read ITK files using SimpleITK
raw_img = sitk.ReadImage(raw_img_filename)
out_img = sitk.ReadImage(out_img_filename)

# print image information
print('image size: {}'.format(raw_img.GetSize()))
print('image origin: {}'.format(raw_img.GetOrigin()))
print('image spacing: {}'.format(raw_img.GetSpacing()))
print('image width: {}'.format(raw_img.GetWidth()))
print('image height: {}'.format(raw_img.GetHeight()))
print('image depth: {}'.format(raw_img.GetDepth()))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
image size: (2560, 3328)
image origin: (0.0, 0.0)
image spacing: (0.07000000029802322, 0.07000000029802322)
image width: 2560
image height: 3328
image depth: 0
1
2
3
4
5
6
**Question:** What is the pixel size of this image?
Answer: The raw_img image has a resolution of 2560 times 3328 (width times height) = 8519680 pixels in total.

Convert ITK image to Numpy array
In order to easily manipulate data, it is convenient to convert it into a numpy format, which can be transformed using the numpy library, and can easily be visualized using the pylab/matplotliblibrary.
Please check the documentation in http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/Python_html/01_Image_Basics.html to find the proper function to transform the SimpleITK image to numpy. Write your code below:

out_np: should contain the numpy array from out_img
raw_np: should contain the numpy array from raw_img
Note: If you are not familiar with Numpy, you can check briefly this tutorial: http://cs231n.github.io/python-numpy-tutorial/

为了便于操作数据,可以方便地将其转换为numpy格式,可以使用numpy库进行转换,并且可以使用pylab/matplotlib库来可视化数据。
可以参考链接 http://insightsoftwareconsortium.github.io/SimpleITK-Notebooks/Python_html/01_Image_Basics.html 来找到合适的函数将图片转为numpy。

out_np: should contain the numpy array from out_img
raw_np: should contain the numpy array from raw_img
提示: 如果你不熟悉Numpy函数,可参考下面的小教程:
http://cs231n.github.io/python-numpy-tutorial/

# convert the ITK image into numpy format
# >> YOUR CODE HERE <<<
out_np = sitk.GetArrayFromImage(out_img)
raw_np = sitk.GetArrayFromImage(raw_img)
1
2
3
4
assert(out_np is not None),"out_np cannot be None"
assert(raw_np is not None),"raw_np cannot be None"

# visualize the two numpy arrays
plt.subplot(1,2,1)
plt.imshow(raw_np, cmap='gray')
plt.title('raw data')
plt.subplot(1,2,2)
plt.imshow(out_np, cmap='gray')
plt.title('gray-level data (target)')
plt.show()
1
2
3
4
5
6
7
8
9
10
11


def sitk_show(img, title=None, margin=0.0, dpi=40):
    nda = sitk.GetArrayFromImage(img)
    #spacing = img.GetSpacing()
    figsize = (1 + margin) * nda.shape[0] / dpi, (1 + margin) * nda.shape[1] / dpi
    #extent = (0, nda.shape[1]*spacing[1], nda.shape[0]*spacing[0], 0)
    extent = (0, nda.shape[1], nda.shape[0], 0)
    fig = plt.figure(figsize=figsize, dpi=dpi)
    ax = fig.add_axes([margin, margin, 1 - 2*margin, 1 - 2*margin])

    plt.set_cmap("gray")
    
    ax.imshow(nda,extent=extent,interpolation=None)
    
    if title:
        plt.title(title)
    
    plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
图像预处理技术——CLAHE
限制对比度自适应直方图均衡(CLAHE算法)是一种效果较好的均衡算法
与普通的自适应直方图均衡相比,CLAHE的 不同地方在于直方图修剪过程,用修剪后的 直方图均衡图像时,图像对比度会更自然。
CLAHE算法步骤
图像分块,以块为单位,先计算直方图,然后修剪直方图,最后均衡;
遍历、操作各个图像块,进行块间双线性插值;
与原图做图层滤色混合操作。(可选)
import cv2
1
# raw and gray-level data in ITK format
raw = cv2.imread('1.png', 0)
equ = cv2.equalizeHist(raw)  # 应用全局直方图均衡化

clahe = cv2.createCLAHE(clipLimit=100, tileGridSize=(8, 8))  # 自适应均衡化,参数可选
cl1 = clahe.apply(raw)

# visualize the two numpy arrays
plt.subplot(3,1,1)
plt.imshow(raw, cmap='gray')
plt.title('raw data')
plt.subplot(3,1,2)
plt.imshow(equ, cmap='gray')
plt.title('equ data')
plt.subplot(3,1,3)
plt.imshow(cl1, cmap='gray')
plt.title('clahe data')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18


常用的图像处理
Implement the three main steps necessary to convert raw data into a gray-level image:

Logaritmic transformation
Intensity inversion
Contrast stretching
将一张原始图片转换为一张灰度图片,需要实现下面3个主要步骤:

对数变换
图像强度反转
对比度拉伸

对数变换
# logarithmic transformation
# >> YOUR CODE HERE <<<
# The mu and d actually stand for depth and intensitiy in the scan
# It does not have to be incorporated into the calculations
print(raw_np)
mammo_log = np.log(raw_np + 1)
mammo_log = mammo_log *(255/np.max(mammo_log))
print("Lowest value in mammo_log:" + str(np.min(mammo_log)))
print("Highest value in mammo_log:" + str(np.max(mammo_log)))
print(mammo_log)
1
2
3
4
5
6
7
8
9
10
[[16383 16383 16383 ... 16383 16383 16383]
 [16383 16383 16383 ... 16383 16383 16383]
 [16383 16383 16383 ... 16383 16383 16383]
 ...
 [ 8832  8832  8832 ...  8832  8832  8832]
 [ 8832  8832  8832 ...  8832  8832  8832]
 [ 8832  8832  8832 ...  8832  8832  8832]]
Lowest value in mammo_log:0.0
Highest value in mammo_log:255.0
[[255.     255.     255.     ... 255.     255.     255.    ]
 [255.     255.     255.     ... 255.     255.     255.    ]
 [255.     255.     255.     ... 255.     255.     255.    ]
 ...
 [238.7654 238.7654 238.7654 ... 238.7654 238.7654 238.7654]
 [238.7654 238.7654 238.7654 ... 238.7654 238.7654 238.7654]
 [238.7654 238.7654 238.7654 ... 238.7654 238.7654 238.7654]]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
assert(mammo_log is not None),"mammo_log cannot be None"

# visualize the result
plt.imshow(mammo_log, cmap='gray')
plt.title('after logaritmic transformation')
1
2
3
4
5
Text(0.5,1,'after logaritmic transformation')
1


图像强度反转
# intensity inversion
# >> YOUR CODE HERE <<<

# In order to make np.invert work, we have to convert floats to ints
# mammo_inv = np.invert(mammo_log.astype(int)) 
# numpy invert is a elementwise operation. The TA told us that we should invert the values by ourself.
mammo_inv = (mammo_log-np.max(mammo_log))*-1
print("Lowest value in mammo_inv:" + str(np.min(mammo_inv)))
print("Highest value in mammo_inv:" + str(np.max(mammo_inv)))
1
2
3
4
5
6
7
8
9
Lowest value in mammo_inv:-0.0
Highest value in mammo_inv:255.0
1
2
assert(mammo_inv is not None),"mammo_inv cannot be None"

# visualize the result
plt.imshow(mammo_inv, cmap='gray')
plt.title('after intensity inversion')
1
2
3
4
5
Text(0.5,1,'after intensity inversion')
1


对比度拉伸
In order to apply the contrast stretching operation, let’s first define a general contrast stretching function. The inputs should be at least (1) the input signal, (2) the window range values p0 and pk, as defined in the lecture.
Note: The end results should not contain intensity values larger than pk or lower than p0.

为了应用对比度拉伸操作,我们首先定义一般的对比度拉伸功能。 输入应至少为:

输入信号,
窗口范围值p0和pk。
注意:最终结果不应包含大于pk或低于p0的强度值。
# contrast stretching
def contrast_stretching(x, p0, pk, q0=0., qk=255.):
    # >>> YOUR CODE HERE <<<
    x_cs = (x-p0)/(pk-p0)
    x_cs[x_cs<=0] = 0 # Clipping, suggested by TA
    x_cs[x_cs>1]  = 1 # Clipping, suggested by TA
    x_cs = q0 + (qk - q0) * x_cs 
    return x_cs
1
2
3
4
5
6
7
8
Now we can apply contrast stretching and visualize the result.

现在我们可以应用对比度拉伸并可视化结果。

# plotting histogram to choose proper boundaries (p0, pk)
hist, bin_edges = np.histogram(mammo_inv, bins=500, range=[75, 110])
plt.bar(bin_edges[:-1], hist, width = 1)
plt.xlim(min(bin_edges), max(bin_edges))
plt.show()   

# pick proper values for p0 and pk
p0 = 85
pk = 100

assert(p0 is not None),"p0 cannot be None"
assert(pk is not None),"pk cannot be None"
1
2
3
4
5
6
7
8
9
10
11
12


mammo_cs = contrast_stretching(mammo_inv, p0, pk)
assert(mammo_cs is not None),"mammo_cs can not be None"

# visualize the result
plt.imshow(mammo_cs, cmap='gray')
plt.show()
1
2
3
4
5
6


You will notice that the result at this stage is already much more readable than the raw data you started from. However, the result is still not as good as the one provided by the mammography manufacturer. In order to check for the differences, we will visualize the histogram of the mammography after inversion (before contrast stretching), after contrast stretching and the target one.

您会注意到此阶段的结果已经比您开始的原始数据更具可读性。 然而,结果仍然不如乳腺X光片制造商提供的效果好。 为了检查两者的差异,我们将在反转后(对比度拉伸之前),对比度拉伸之后和目标拉伸之后的结果和可视化乳腺X光片厂商处理图的直方图进行比较。

# visualize and compare histograms
plt.subplot(1,3,1)
plt.hist(mammo_inv.flatten(), 100)
plt.title('before contrast stretching')
plt.subplot(1,3,2)
plt.hist(mammo_cs.flatten(), 100)
plt.title('after contrast stretching')
plt.subplot(1,3,3)
plt.hist(out_np.flatten(), 100)
plt.title('target')
plt.show()
1
2
3
4
5
6
7
8
9
10
11


**Question:** How did you define the values of p0 and pk? How much does the result change when this parameters sligthly change? Could you deduce this by having a look at the histogram?
By plotting the histogram of the inverted image we looked out for general peaks and isolated each one and used these for possible candidates for contrast stretching. After isolating and trying out three different peaks we settled down with a range between 85 and 100 because it produced a similar solution to the target. The first peak around 0 and 30 only generated a separation between the foreground and the background and therefore was not the solution we were looking for. If you change these parameters you just restrict the range you want to incorporate into the contrast stretching procedure. A slight change in these parameters could lead to different images with different levels of detail. The histogram is therefore a useful tool to isolate possible candidates for contrast stretching.

通过绘制倒置图像的直方图,我们寻找一般峰值并隔离每个峰值,并将它们用于对比度拉伸的候选参数。 在分离并尝试了三个不同的峰值之后,我们确定了85到100之间的范围,因为它产生了与厂商处理图片的效果。 0和30左右的第一个峰值仅产生前景和背景之间的分离,因此不是我们正在寻找的解决参数。 如果更改这些参数,则只需将要合并的范围限制为对比度拉伸过程。 这些参数的微小变化可能导致具有不同细节水平的不同图像。 因此,直方图是隔离对比度拉伸的参数选择的有用工具。

直方图均衡/匹配
The step of contrast stretching could be replaced by a histogram equalization step. In this way, we assume that the target image is known and accessible, from which we will learn some intensity value correspondance function, known as look-up-table (LUT). A LUT is a table that has entries that correspond to all possible values in the input image, and each value is mapped to an output value, with the aim of mimicking the intensity distribution of the target image, the vendor mammography in our case.

对比度拉伸的步骤可以用直方图均衡来代替。 通过这种方式,我们假设目标图像是已知的,我们将从中学习一些强度值对应函数,称为查找表(LUT)。 LUT是一个表格,其条目对应于输入图像中的所有可能值,并且每个值都映射到输出值,目的是模仿目标图像的强度分布,在我们的案例中是乳腺X光片供应商处理结果。

Implement a function that takes as input the histogram to transform and the target histogram and return a LUT.

# function to do histogram matching

def get_histogram_matching_lut(h_input, h_template):
    ''' h_input: histogram to transfrom, h_template: reference'''
    if len(h_input) != len(h_template):
        print('histograms length mismatch!')
        return False
    
    # >> YOUR CODE HERE <<
    LUT = np.zeros(len(h_input))
    H_input = np.cumsum(h_input) # Cumulative distribution of h_input
    H_template = np.cumsum(h_template) # Cumulative distribution of h_template
    
    for i in range(len(H_template)):
        input_index = H_input[i]
        new_index = (np.abs(H_template-input_index)).argmin()
        LUT[i] = new_index
    
    return LUT, H_input, H_template
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
Now tha the function get_histogram_matching_lut()has been implemented, you can execute the next cell, which uses it, and visualize the result of the mammography image converted using histogram matching.

现在已经实现了函数get_histogram_matching_lut(),你可以执行下一个使用它的单元格,并可视化使用直方图匹配转换的乳腺X光片图像的结果。

# rescale images between [0,1]
out_np = out_np.astype(float)
mammo_inv_norm = (mammo_inv - mammo_inv.flatten().min())/(mammo_inv.flatten().max() - mammo_inv.flatten().min())
mammo_out_norm = (out_np - out_np.flatten().min())/(out_np.flatten().max() - out_np.flatten().min())

n_bins = 4000 # define the number of bins
hist_inv = np.histogram(mammo_inv_norm, bins=np.linspace(0., 1., n_bins+1))
hist_out = np.histogram(mammo_out_norm, bins=np.linspace(0., 1., n_bins+1))

# compute LUT
LUT,H_input,H_template = get_histogram_matching_lut(hist_inv[0], hist_out[0])
assert(LUT        is not None),"LUT cannot be None"
assert(H_input    is not None),"H_input cannot be None"
assert(H_template is not None),"H_template cannot be None"

# histograms before matching
plt.suptitle('BEFORE HISTOGRAM MATCHING')
plt.subplot(1,2,1); plt.hist(mammo_inv_norm.flatten())
plt.title('histogram input')
plt.subplot(1,2,2); plt.hist(mammo_out_norm.flatten())
plt.title('histogram target')
plt.show()

# plot cumulative histogram
plt.suptitle('CUMULATIVE HISTOGRAMS')
plt.subplot(1,2,1); plt.plot(H_input)
plt.title('cumulative histogram input')
plt.subplot(1,2,2); plt.plot(H_template)
plt.title('cumulative histogram target')
plt.show()    
    
# apply histogram matching
mammo_lut = LUT[(mammo_inv_norm * (n_bins-1)).astype(int)]

# visual result
plt.suptitle('VISUAL RESULT')
plt.subplot(1,2,1); plt.imshow(mammo_lut.squeeze(), cmap='gray')
plt.title('converted image')
plt.subplot(1,2,2); plt.imshow(out_np, cmap='gray')
plt.title('target')
plt.show()

# histograms after matching
plt.suptitle('AFTER HISTOGRAM MATCHING')
plt.subplot(1,2,1)
plt.hist(mammo_lut.flatten())
plt.subplot(1,2,2)
plt.hist(out_np.flatten())
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

Question:
你是如何选择用于进行直方图匹配的分箱数? 结果是否取决于分箱的数量?

Take the size of overall bin count from the target histogram. It seems that the result does not actually depend on the number of bins because the converted image does not change (much).

从目标直方图中获取总分箱数的大小。 似乎结果实际上并不依赖于分箱的数量,因为转换后的图像不会发生变化(很多)。

病理切片的归一化(直方图匹配)

In the previous exercise, we implemented a histogram matching function and used it to adapt a given mammography image to a given target image. In that case, the goal was to enhance relevant information in raw mammography data and make it visible as a gray-scale image.

The same technique can be applied to the field of digital pathology, but with the aim of solving a different problem, the variability of stain across images.
In pathology, tissue samples are cut and stained with specific dyes in order to enhance some tissues that are relevant for the diagnosis. The most commonly used staining is called Hematoxylyn and Eosin (H&E), which is routinely applied for diagnostic purposes.
The problem with H&E is that there is a large variability of stain across laboratories, and even in the same laboratory, when staining is done in different days of the week. This is because the final result strongly depends on the type and the density of the dyes and on the time the tissue is actually exposed to the dye.

The examples on the right are images of colorectal cancer tissue samples, extracted from a publicly available dataset (https://zenodo.org/record/53169#.WJRAC_krIuU), where the appearance, mainly the colour, of the HE-stained images, is different.
Histogram matching is a technique that can help solve this problem, since we can think of adapting the distribution of colors per channel (R,G,B) by treating each channel independently.

When working with digital pathology images, it is worth noting that the image size is often big. Typical histopathology images are gigapixel images (think of Google maps to get an indea) in the order of 100,000 x 100,000 pixel. However, for the sake of simplicity, in this assignment we will only use tiles of 5000x5000 px.

在上一个练习中,我们实现了直方图匹配功能,并使用它来使给定的乳腺X光片图像适应给定的目标图像。在这种情况下,目标是增强原始乳腺X光片数据中的相关信息,并使其作为灰度图像更利于查看。
相同的技术可以应用于数字病理学领域,但是为了解决不同的问题,图像中的染色剂的可变性。
在病理学中,切割组织样品并用特定染料染色,以增强与诊断相关的一些组织。最常用的染色称为Hematoxylyn和Eosin(H&E),常规用于诊断目的。
H&E的问题在于,在一周的不同日期进行染色时,实验室中的染色变异很大,甚至在同一实验室也是如此。这是因为最终结果很大程度上取决于染料的类型和密度以及组织实际暴露于染色剂的时间。
右边的例子是从公开可用的数据集(https://zenodo.org/record/53169#.WJRAC_krIuU) 中提取的结肠直肠癌组织样本的图像,其中HE染色图像的外观,主要是颜色是不同的。
直方图匹配是一种可以帮助解决这个问题的技术,因为我们可以考虑通过独立处理每个通道来调整每个通道(R,G,B)的颜色分布。
使用数字病理切片图像时,值得注意的是图像大小通常很大。典型的组织病理学图像是千兆像素图像,大约100,000 x 100,000像素。但是,为了简单起见,在此任务中,我们将仅使用5000x5000像素的图块。

Load the slides
# load data
HE1 = np.asarray(Image.open('./assignment_1/CRC-Prim-HE-05_APPLICATION.tif'))
HE2 = np.asarray(Image.open('./assignment_1/CRC-Prim-HE-10_APPLICATION.tif'))

print(HE1.shape)
print(HE2.shape)

plt.subplot(1,2,1); plt.imshow(HE1); plt.title('HE1')
plt.subplot(1,2,2); plt.imshow(HE2); plt.title('HE2')
1
2
3
4
5
6
7
8
9
(5000, 5000, 3)
(5000, 5000, 3)

Text(0.5,1,'HE2')
1
2
3
4
5
6
7
8


染色剂归一化
Implement your stain normalization function based on histogram matching based on the following definition.

def stain_normalization(input_img, target_img, n_bins=100):
    """ Stain normalization based on histogram matching. """
    
    print("Lowest value in input_img:" + str(np.min(input_img)))
    print("Highest value in input_img:" + str(np.max(input_img)))
    
    print("Lowest value in target_img:" + str(np.min(target_img)))
    print("Highest value in target_img:" + str(np.max(target_img)))
    
    normalized_img = np.zeros(input_img.shape)
    
    input_img = input_img.astype(float) # otherwise we get a complete yellow image
    target_img = target_img.astype(float) # otherwise we get a complete blue image
    
    # Used resource: https://stackoverflow.com/a/42463602
    # normalize input_img
    input_img_min = input_img.min(axis=(0, 1), keepdims=True)
    input_img_max = input_img.max(axis=(0, 1), keepdims=True)
    input_norm = (input_img - input_img_min)/(input_img_max - input_img_min)
    
    # normalize target_img
    target_img_min = target_img.min(axis=(0, 1), keepdims=True)
    target_img_max = target_img.max(axis=(0, 1), keepdims=True)
    target_norm = (target_img - target_img_min)/(target_img_max - target_img_min)
    
    # Go through all three channels
    for i in range(3):
        input_hist = np.histogram(input_norm[:,:,i], bins=np.linspace(0, 1, n_bins + 1))
        target_hist = np.histogram(target_norm[:,:,i], bins=np.linspace(0, 1, n_bins + 1))
        LUT, H_input, H_template = get_histogram_matching_lut(input_hist[0],target_hist[0])
        normalized_img[:,:,i] = LUT[(input_norm[:,:,i] * (n_bins - 1)).astype(int)]
    
    normalized_img = normalized_img / n_bins
    
    return normalized_img
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Now we can use the implemented function to do stain normalization and check the actual result.

# transform HE1 to match HE2
HE1_norm = stain_normalization(HE1, HE2);
assert(HE1_norm is not None),"HE1_norm can not be None"

plt.subplot(1,3,1)
plt.imshow(HE1); plt.title('HE1 before normalization')
plt.subplot(1,3,2)
plt.imshow(HE1_norm); plt.title('HE1 after normalization')
plt.subplot(1,3,3)
plt.imshow(HE2); plt.title('target')
plt.show()

# transform HE2 to match HE1
HE2_norm = stain_normalization(HE2, HE1);
plt.subplot(1,3,1); plt.imshow(HE2)
plt.title('HE2 before normalization')
plt.subplot(1,3,2); plt.imshow(HE2_norm)
plt.title('HE2 after normalization')
plt.subplot(1,3,3); plt.imshow(HE1)
plt.title('target')
plt.show()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Lowest value in input_img:0
Highest value in input_img:255
Lowest value in target_img:0
Highest value in target_img:255
1
2
3
4


Lowest value in input_img:0
Highest value in input_img:255
Lowest value in target_img:0
Highest value in target_img:255
1
2
3
4

--------------------- 
作者:ericliu2017 
来源:CSDN 
原文:https://blog.csdn.net/myboyliu2007/article/details/85112421 
版权声明:本文为博主原创文章,转载请附上博文链接!

猜你喜欢

转载自blog.csdn.net/hzp666/article/details/85197405