C#
2015.03.11 09:08
Fellow Oak DICOM SDK를 이용한 이미지에서 DICOM으로 변환방법
다물칸 주소복사
조회 수 229 추천 수 0 댓글 0
구분 | 팁&트릭 |
---|---|
출처 | 내가작성 |
해당 라이브러리 라이선스: MS-PL
GIT : https://github.com/hdesouky/fo-dicom
Forum : https://groups.google.com/forum/#!forum/fo-dicom
우선 이녀석을 프로젝트에 임포트하는 방법
GIT를 이용하거나 NUGet을 이용하여 Import합니다.
새로운 프로젝트 또는 사용할 프로젝트에서 Nuget을 실행하여
1. NLog (3.2.0.0)을 프로젝트에 추가합니다. (Fellow Oak에서 기본사용중이라 NLog가 없으면 설치가 안됩니다.)
2. DICOM으로 검색하면 맨위에 Fellow Oak가 있습니다. 그거 추가합니다.
새 클래스를 추가합니다.
public class BitmapToDicom { public static void ImportImage(string Imagefile, string TargetPath) { Bitmap bitmap = new Bitmap(Imagefile); bitmap = GetValidImage(bitmap); int rows, columns; byte[] pixels = GetPixels(bitmap, out rows, out columns); MemoryByteBuffer buffer = new MemoryByteBuffer(pixels); DicomDataset dataset = new DicomDataset(); string sopInstanceUID = FillDataset(dataset); dataset.Add(DicomTag.PhotometricInterpretation, PhotometricInterpretation.Rgb.Value); dataset.Add(DicomTag.Rows, (ushort)rows); dataset.Add(DicomTag.Columns, (ushort)columns); DicomPixelData pixelData = DicomPixelData.Create(dataset, true); pixelData.BitsStored = 8; pixelData.BitsAllocated = 8; pixelData.SamplesPerPixel = 3; pixelData.HighBit = 7; pixelData.PixelRepresentation = 0; pixelData.PlanarConfiguration = 0; pixelData.AddFrame(buffer); DicomFile dicomfile = new DicomFile(dataset); string TargetFile = Path.Combine(TargetPath, sopInstanceUID + ".dcm"); dicomfile.Save(TargetFile); } private static string FillDataset(DicomDataset dataset) { //type 1 attributes. dataset.Add(DicomTag.SOPClassUID, DicomUID.SecondaryCaptureImageStorage); dataset.Add(DicomTag.StudyInstanceUID, GenerateUid()); dataset.Add(DicomTag.SeriesInstanceUID, GenerateUid()); DicomUID sopInstanceUID = GenerateUid(); dataset.Add(DicomTag.SOPInstanceUID, sopInstanceUID); //type 2 attributes dataset.Add(DicomTag.PatientID, "12345"); dataset.Add(DicomTag.PatientName, "Hong, Kil Dong"); dataset.Add(DicomTag.PatientBirthDate, "00000000"); dataset.Add(DicomTag.PatientSex, "M"); dataset.Add(DicomTag.StudyDate, DateTime.Now); dataset.Add(DicomTag.StudyTime, DateTime.Now); dataset.Add(DicomTag.AccessionNumber, string.Empty); dataset.Add(DicomTag.ReferringPhysicianName, string.Empty); dataset.Add(DicomTag.StudyID, "1"); dataset.Add(DicomTag.SeriesNumber, "1"); dataset.Add(DicomTag.ModalitiesInStudy, "CR"); dataset.Add(DicomTag.Modality, "CR"); dataset.Add(DicomTag.NumberOfStudyRelatedInstances, "1"); dataset.Add(DicomTag.NumberOfStudyRelatedSeries, "1"); dataset.Add(DicomTag.NumberOfSeriesRelatedInstances, "1"); dataset.Add(DicomTag.PatientOrientation, "F/A"); dataset.Add(DicomTag.ImageLaterality, "U"); return sopInstanceUID.ToString(); } private static DicomUID GenerateUid() { StringBuilder uid = new StringBuilder(); uid.Append("1.08.1982.10121984.2.0.07").Append('.').Append(DateTime.UtcNow.Ticks); return new DicomUID(uid.ToString(), "SOP Instance UID", DicomUidType.SOPInstance); } private static Bitmap GetValidImage(Bitmap bitmap) { if (bitmap.PixelFormat != PixelFormat.Format24bppRgb) { Bitmap old = bitmap; using (old) { bitmap = new Bitmap(old.Width, old.Height, PixelFormat.Format24bppRgb); using (System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap)) { g.DrawImage(old, 0, 0, old.Width, old.Height); } } } return bitmap; } private static byte[] GetPixels(Bitmap image, out int rows, out int columns) { rows = image.Height; columns = image.Width; if (rows % 2 != 0 && columns % 2 != 0) --columns; BitmapData data = image.LockBits(new Rectangle(0, 0, columns, rows), ImageLockMode.ReadOnly, image.PixelFormat); IntPtr bmpData = data.Scan0; try { int stride = columns * 3; int size = rows * stride; byte[] pixelData = new byte[size]; for (int i = 0; i < rows; ++i) Marshal.Copy(new IntPtr(bmpData.ToInt64() + i * data.Stride), pixelData, i * stride, stride); //swap BGR to RGB SwapRedBlue(pixelData); return pixelData; } finally { image.UnlockBits(data); } } private static void SwapRedBlue(byte[] pixels) { for (int i = 0; i < pixels.Length; i += 3) { byte temp = pixels[i]; pixels[i] = pixels[i + 2]; pixels[i + 2] = temp; } } }
사용방법
private void simpleButton1_Click(object sender, EventArgs e) { string strFile = @"D:\test.jpg"; // 아래 함수 따라가보면 FillDataSet에서 환자정보/처방정보등을 넣어주는 곳이 있습니다. 거기서 DB등에서 가져온 데이터를 넣어주면 됩니다. BitmapToDicom.ImportImage(strFile, @"D:\"); }