8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비
전제
여기서 말하는 다운 스케일링은 이미지의 표본화에서 말하는 다운 스케일을 의미합니다.
이미지 다운 스케일링
여기에서는 그레이 스케일 이미지를 대상으로 이야기합니다.
일반적으로 그레이 스케일 이미지는 8비트, 16비트, 32비트 등 '1채널'의 픽셀 모음으로 구성되어 있습니다.
(RGB등의 컬러 화상은, R, G, B 각각의 채널이 있어, 이것들을 통합해 화상으로 하고 있습니다.이 점은 중요합니다. 바꾸어 말하면, RGB 화상은, 8-bit grayscale 화상이 3장 분 있다고 말할 수 있습니다.엄격하게는 α성분(투명도를 지정하는 성분)이 있는 경우도 있습니다만, α성분도 8-bit grayscale 화상이 1장분 증가한 것 같습니다.)
자주 의료 영상으로 사용되는 것이 16-bit 이미지입니다.
16비트 이미지는 0-65535 사이의 숫자를 픽셀 값으로 유지할 수 있습니다.
반면 8비트 이미지는 0-255까지의 숫자만 유지할 수 있습니다.
(부호 첨부, 부호 없음에 대해서는 여기에서는 감히 만지지 않습니다.)
화상 처리나 기계 학습 등에서는, 계산을 간편하게 하기 위해서, 또는 처리를 고속으로 하기 위해서, 높은 비트의 화상을 8-bit 화상에 다운 스케일 해 변환하는 처리를 실시합니다.
이 다운 스케일 때 작법을 잘못하면 이미지가 이상하게되기 때문에주의가 필요합니다.
샘플 이미지
JIRA의 흉부 X 선을 빌려드립니다.
LEE와 붙어 있는 것은 비압축 이미지라는 의미입니다. 이것을 사용합니다.
샘플 이미지
다운 스케일 예 (16-bit ~ 8-bit)
먼저 이미지를로드하고 numpy의 ndarray로 처리하기 위해 pydicom을 사용합니다.
!pip install pydicom
데이터를 로드합니다.
import pydicom
import numpy as np
ds = pydicom.dcmread('CR_LEE_IR87a.dcm')#パスを指定する
#ピクセルを取り出す(ndarrayとして扱っています)
pixels = ds.pixel_array
# 左右反転しているので戻す
pixels = np.fliplr(pixels)
#画像として表示
import matplotlib.pyplot as plt
plt.imshow(pixels,cmap="gray")#2つとも必要
plt.show()
이를 위해 이 이미지가 8비트가 아닌지 확인합니다.
DICOM 태그에서도 알 수 있지만 직접 픽셀을 보아도 알 수 있습니다.
# この画像の画素を見てみる
print (pixels[512,512]) # 3186
픽셀(x, y)(512,512)의 픽셀 값은 3186임을 확인할 수 있습니다.
즉, 0-255 사이에 없고, 실수가 아니기 때문에 16-bit인 것을 알 수 있습니다.
이제 준비가 되었습니다.
numpy
단순히 8bit로 변환해 보겠습니다.
# numpyで8 bit変換してみる
np_img = pixels.astype('uint8')
plt.imshow(np_img,cmap="gray")
plt.show()
다르다.
Pillow
# pillowを使う
from PIL import Image, ImageOps
pil_img = Image.fromarray(pixels)
pil_img = pil_img.convert('L')#L:grayscale
plt.imshow(pil_img,cmap="gray")#2つとも必要
plt.show()
print(np.asarray(pil_img)[512,512]) #255, 完全にアウトオブレンジな感じです。
이것도 다르구나.
OpenCV
# opencvを使う
# 変換可能
# pixels は16 bit配列の変数とする。
import cv2
cv_img8 = np.zeros(pixels.shape) # dummy変数
cv_img8 = cv2.convertScaleAbs(pixels-np.min(pixels), cv_img8, 255/(np.max(pixels)-np.min(pixels)), beta=0) # 2021/6/22修正
cv_img8 = cv_img8.astype(np.uint8)
plt.imshow(cv_img8, cmap="gray")
plt.show()
print(cv_img8[512,512])
Scikit-image
# skimageを使う
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#2つとも必要
plt.show()
오! 라고 생각하지만, 이것은 눈부시고, 잘 보면 화소가 붕괴되고 있다.
ImageJ 알고리즘을 이용한 다운 스케일
ImageJ의 다운 스케일을 구현해 보았습니다.
최대값, 최소값 및 스케일링 팩터로 정규화합니다.
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
이것 이것. 원하는 이미지입니다.
Visionary Imaging Services, Inc.
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
여기에서는 그레이 스케일 이미지를 대상으로 이야기합니다.
일반적으로 그레이 스케일 이미지는 8비트, 16비트, 32비트 등 '1채널'의 픽셀 모음으로 구성되어 있습니다.
(RGB등의 컬러 화상은, R, G, B 각각의 채널이 있어, 이것들을 통합해 화상으로 하고 있습니다.이 점은 중요합니다. 바꾸어 말하면, RGB 화상은, 8-bit grayscale 화상이 3장 분 있다고 말할 수 있습니다.엄격하게는 α성분(투명도를 지정하는 성분)이 있는 경우도 있습니다만, α성분도 8-bit grayscale 화상이 1장분 증가한 것 같습니다.)
자주 의료 영상으로 사용되는 것이 16-bit 이미지입니다.
16비트 이미지는 0-65535 사이의 숫자를 픽셀 값으로 유지할 수 있습니다.
반면 8비트 이미지는 0-255까지의 숫자만 유지할 수 있습니다.
(부호 첨부, 부호 없음에 대해서는 여기에서는 감히 만지지 않습니다.)
화상 처리나 기계 학습 등에서는, 계산을 간편하게 하기 위해서, 또는 처리를 고속으로 하기 위해서, 높은 비트의 화상을 8-bit 화상에 다운 스케일 해 변환하는 처리를 실시합니다.
이 다운 스케일 때 작법을 잘못하면 이미지가 이상하게되기 때문에주의가 필요합니다.
샘플 이미지
JIRA의 흉부 X 선을 빌려드립니다.
LEE와 붙어 있는 것은 비압축 이미지라는 의미입니다. 이것을 사용합니다.
샘플 이미지
다운 스케일 예 (16-bit ~ 8-bit)
먼저 이미지를로드하고 numpy의 ndarray로 처리하기 위해 pydicom을 사용합니다.
!pip install pydicom
데이터를 로드합니다.
import pydicom
import numpy as np
ds = pydicom.dcmread('CR_LEE_IR87a.dcm')#パスを指定する
#ピクセルを取り出す(ndarrayとして扱っています)
pixels = ds.pixel_array
# 左右反転しているので戻す
pixels = np.fliplr(pixels)
#画像として表示
import matplotlib.pyplot as plt
plt.imshow(pixels,cmap="gray")#2つとも必要
plt.show()
이를 위해 이 이미지가 8비트가 아닌지 확인합니다.
DICOM 태그에서도 알 수 있지만 직접 픽셀을 보아도 알 수 있습니다.
# この画像の画素を見てみる
print (pixels[512,512]) # 3186
픽셀(x, y)(512,512)의 픽셀 값은 3186임을 확인할 수 있습니다.
즉, 0-255 사이에 없고, 실수가 아니기 때문에 16-bit인 것을 알 수 있습니다.
이제 준비가 되었습니다.
numpy
단순히 8bit로 변환해 보겠습니다.
# numpyで8 bit変換してみる
np_img = pixels.astype('uint8')
plt.imshow(np_img,cmap="gray")
plt.show()
다르다.
Pillow
# pillowを使う
from PIL import Image, ImageOps
pil_img = Image.fromarray(pixels)
pil_img = pil_img.convert('L')#L:grayscale
plt.imshow(pil_img,cmap="gray")#2つとも必要
plt.show()
print(np.asarray(pil_img)[512,512]) #255, 完全にアウトオブレンジな感じです。
이것도 다르구나.
OpenCV
# opencvを使う
# 変換可能
# pixels は16 bit配列の変数とする。
import cv2
cv_img8 = np.zeros(pixels.shape) # dummy変数
cv_img8 = cv2.convertScaleAbs(pixels-np.min(pixels), cv_img8, 255/(np.max(pixels)-np.min(pixels)), beta=0) # 2021/6/22修正
cv_img8 = cv_img8.astype(np.uint8)
plt.imshow(cv_img8, cmap="gray")
plt.show()
print(cv_img8[512,512])
Scikit-image
# skimageを使う
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#2つとも必要
plt.show()
오! 라고 생각하지만, 이것은 눈부시고, 잘 보면 화소가 붕괴되고 있다.
ImageJ 알고리즘을 이용한 다운 스케일
ImageJ의 다운 스케일을 구현해 보았습니다.
최대값, 최소값 및 스케일링 팩터로 정규화합니다.
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
이것 이것. 원하는 이미지입니다.
Visionary Imaging Services, Inc.
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
먼저 이미지를로드하고 numpy의 ndarray로 처리하기 위해 pydicom을 사용합니다.
!pip install pydicom
데이터를 로드합니다.
import pydicom
import numpy as np
ds = pydicom.dcmread('CR_LEE_IR87a.dcm')#パスを指定する
#ピクセルを取り出す(ndarrayとして扱っています)
pixels = ds.pixel_array
# 左右反転しているので戻す
pixels = np.fliplr(pixels)
#画像として表示
import matplotlib.pyplot as plt
plt.imshow(pixels,cmap="gray")#2つとも必要
plt.show()
이를 위해 이 이미지가 8비트가 아닌지 확인합니다.
DICOM 태그에서도 알 수 있지만 직접 픽셀을 보아도 알 수 있습니다.
# この画像の画素を見てみる
print (pixels[512,512]) # 3186
픽셀(x, y)(512,512)의 픽셀 값은 3186임을 확인할 수 있습니다.
즉, 0-255 사이에 없고, 실수가 아니기 때문에 16-bit인 것을 알 수 있습니다.
이제 준비가 되었습니다.
numpy
단순히 8bit로 변환해 보겠습니다.
# numpyで8 bit変換してみる
np_img = pixels.astype('uint8')
plt.imshow(np_img,cmap="gray")
plt.show()
다르다.
Pillow
# pillowを使う
from PIL import Image, ImageOps
pil_img = Image.fromarray(pixels)
pil_img = pil_img.convert('L')#L:grayscale
plt.imshow(pil_img,cmap="gray")#2つとも必要
plt.show()
print(np.asarray(pil_img)[512,512]) #255, 完全にアウトオブレンジな感じです。
이것도 다르구나.
OpenCV
# opencvを使う
# 変換可能
# pixels は16 bit配列の変数とする。
import cv2
cv_img8 = np.zeros(pixels.shape) # dummy変数
cv_img8 = cv2.convertScaleAbs(pixels-np.min(pixels), cv_img8, 255/(np.max(pixels)-np.min(pixels)), beta=0) # 2021/6/22修正
cv_img8 = cv_img8.astype(np.uint8)
plt.imshow(cv_img8, cmap="gray")
plt.show()
print(cv_img8[512,512])
Scikit-image
# skimageを使う
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#2つとも必要
plt.show()
오! 라고 생각하지만, 이것은 눈부시고, 잘 보면 화소가 붕괴되고 있다.
ImageJ 알고리즘을 이용한 다운 스케일
ImageJ의 다운 스케일을 구현해 보았습니다.
최대값, 최소값 및 스케일링 팩터로 정규화합니다.
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
이것 이것. 원하는 이미지입니다.
Visionary Imaging Services, Inc.
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# numpyで8 bit変換してみる
np_img = pixels.astype('uint8')
plt.imshow(np_img,cmap="gray")
plt.show()
# pillowを使う
from PIL import Image, ImageOps
pil_img = Image.fromarray(pixels)
pil_img = pil_img.convert('L')#L:grayscale
plt.imshow(pil_img,cmap="gray")#2つとも必要
plt.show()
print(np.asarray(pil_img)[512,512]) #255, 完全にアウトオブレンジな感じです。
이것도 다르구나.
OpenCV
# opencvを使う
# 変換可能
# pixels は16 bit配列の変数とする。
import cv2
cv_img8 = np.zeros(pixels.shape) # dummy変数
cv_img8 = cv2.convertScaleAbs(pixels-np.min(pixels), cv_img8, 255/(np.max(pixels)-np.min(pixels)), beta=0) # 2021/6/22修正
cv_img8 = cv_img8.astype(np.uint8)
plt.imshow(cv_img8, cmap="gray")
plt.show()
print(cv_img8[512,512])
Scikit-image
# skimageを使う
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#2つとも必要
plt.show()
오! 라고 생각하지만, 이것은 눈부시고, 잘 보면 화소가 붕괴되고 있다.
ImageJ 알고리즘을 이용한 다운 스케일
ImageJ의 다운 스케일을 구현해 보았습니다.
최대값, 최소값 및 스케일링 팩터로 정규화합니다.
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
이것 이것. 원하는 이미지입니다.
Visionary Imaging Services, Inc.
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# opencvを使う
# 変換可能
# pixels は16 bit配列の変数とする。
import cv2
cv_img8 = np.zeros(pixels.shape) # dummy変数
cv_img8 = cv2.convertScaleAbs(pixels-np.min(pixels), cv_img8, 255/(np.max(pixels)-np.min(pixels)), beta=0) # 2021/6/22修正
cv_img8 = cv_img8.astype(np.uint8)
plt.imshow(cv_img8, cmap="gray")
plt.show()
print(cv_img8[512,512])
# skimageを使う
import skimage
sk_img = skimage.img_as_ubyte(pixels)
plt.imshow(sk_img,cmap="gray")#2つとも必要
plt.show()
오! 라고 생각하지만, 이것은 눈부시고, 잘 보면 화소가 붕괴되고 있다.
ImageJ 알고리즘을 이용한 다운 스케일
ImageJ의 다운 스케일을 구현해 보았습니다.
최대값, 최소값 및 스케일링 팩터로 정규화합니다.
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
이것 이것. 원하는 이미지입니다.
Visionary Imaging Services, Inc.
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
# ImageJから拝借したノーマリゼーション
amin=np.amin(pixels)
amax=np.amax(pixels)
scale = 255.0/(amax-amin) # 256.0/(amax-amin+1)
pixelsByte = np.copy(pixels)
# pixelsByte = pixelsByte - amin # 最小値は差分 20210622修正
pixelsByte = pixelsByte*scale # 0-255の範囲にリスケール
# np.clip(pixelsByte,0,255) # 冗長でした
pixelsByte = np.uint8(pixelsByte) # 符号なしバイトに変換
print(np.asarray(pixelsByte)[512,512])
plt.imshow(pixelsByte,cmap="gray")
plt.show()
Reference
이 문제에 관하여(8비트 그레이스케일 이미지로 다운 스케일링 및 이미지 대비), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/tatsunidas/items/40c3b1812e132edfaf7f텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)