void CDicomViewerView::DrawDicomImage(CDC* pDC) { CRect clientRect; this->GetClientRect(&clientRect); int nWidth=clientRect.Width(),nHeight=clientRect.Height(); CDC MemDC; //首先定义一个显示设备对象 CBitmap MemBitmap;//定义一个位图对象 //随后建立与屏幕显示兼容的内存显示设备 MemDC.CreateCompatibleDC(NULL); //这时还不能绘图,因为没有地方画 ^_^ //下面建立一个与屏幕显示兼容的位图,至于位图的大小嘛,可以用窗口的大小 MemBitmap.CreateCompatibleBitmap(pDC,nWidth,nHeight); //将位图选入到内存显示设备中 //只有选入了位图的内存显示设备才有地方绘图,画到指定的位图上 CBitmap *pOldBit=MemDC.SelectObject(&MemBitmap); //先用背景色将位图清除干净,这里我用的是白色作为背景 //你也可以用自己应该用的颜色 MemDC.FillSolidRect(0,0,nWidth,nHeight,RGB(0,0,0)); CDicomViewerDoc* pDoc = GetDocument(); if(pDoc->m_pDicomImage != 0){ E_DecompressionColorSpaceConversion opt_decompCSconversion = EDC_photometricInterpretation; E_UIDCreation opt_uidcreation = EUC_default; E_PlanarConfiguration opt_planarconfig = EPC_default; OFBool opt_verbose = OFFalse; DJDecoderRegistration::registerCodecs( opt_decompCSconversion, opt_uidcreation, opt_planarconfig, opt_verbose); //根据传输语法构造 DicomImage 从 fstart 帧开始一共 fcount 帧 DicomImage *pDicomImg = pDoc->m_pDicomImage;//new DicomImage(pDoc->m_pFilePathName); //DicomImage *pNewDicomImg = pDicomImg->createScaledImage((const unsigned long)1024,1024); LPBITMAPINFOHEADER m_lpBMIH = (LPBITMAPINFOHEADER) new char [sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256]; m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER); m_lpBMIH->biWidth = pDicomImg->getWidth(); m_lpBMIH->biHeight = pDicomImg->getHeight(); m_lpBMIH->biPlanes = 1; m_lpBMIH->biBitCount = 24; m_lpBMIH->biCompression = BI_RGB; m_lpBMIH->biSizeImage = 0; m_lpBMIH->biXPelsPerMeter = 0; m_lpBMIH->biYPelsPerMeter = 0; pDicomImg->setWindow(pDoc->m_dCurrentWindowCenter, pDoc->m_dCurrentWindowWidth); //得到 DICOM文件第 frame 的 DIB数据(假设是 24 位的) unsigned long bufSize = 0; void* m_pDicomDibits; bufSize =pDicomImg->createWindowsDIB(m_pDicomDibits, bufSize, 0, 24, 1, 1); double originalX = (clientRect.Width() - m_lpBMIH->biWidth)/2; double originalY = (clientRect.Height() - m_lpBMIH->biHeight)/2; StretchDIBits (MemDC.GetSafeHdc(),originalX,originalY, m_lpBMIH->biWidth, m_lpBMIH ->biHeight,0,0,m_lpBMIH->biWidth,m_lpBMIH->biHeight, m_pDicomDibits, (LPBITMAPINFO) m_lpBMIH,DIB_RGB_COLORS,SRCCOPY); delete m_pDicomDibits; } //将内存中的图拷贝到屏幕上进行显示 pDC->BitBlt(0,0,nWidth,nHeight,&MemDC,0,0,SRCCOPY); MemBitmap.DeleteObject(); MemDC.DeleteDC(); }
DicomImage *loadNextInSeries(string dicomStem, int series) { // set up series info static int lastseries = -1; static int lastframe = 0; int frame; if(series != lastseries) { lastseries = series; frame = 1; } else { frame = lastframe+1; } char filename[256]; sprintf(filename, "%s-%d-%d.dcm", dicomStem.c_str(), series, frame); cout << "loading dicom " << filename << endl; DicomImage *image = new DicomImage(filename); if (image == NULL || image->getStatus() != EIS_Normal) { cerr << "Error: cannot load DICOM image (" << DicomImage::getString(image->getStatus()) << ")" << endl; return NULL; } lastframe = frame; lastseries = series; return image; }
uint ImageInstance::getPixelValue(long x, long y, EP_Representation &r) const { DicomImage *image; if (rawType) image = rawImage; else image = dcmImage; if (image) { const DiPixel* pixel = image->getInterData(); if (pixel && (x < (long)image->getWidth()) && (x >= 0) && (y < (long)image->getHeight()) && (y >= 0)) { r = pixel->getRepresentation(); switch (r) { case EPR_Sint8: case EPR_Uint8: return *((char*)(pixel->getData()) + (y * image->getWidth() + x)); case EPR_Sint16: case EPR_Uint16: return *((short*)(pixel->getData()) + (y * image->getWidth() + x)); case EPR_Sint32: case EPR_Uint32: return *((int*)(pixel->getData()) + (y * image->getWidth() + x)); } } } r = (EP_Representation)-1; return 0; }
bool ImageInstance::dcm2bmpHelper(DicomImage &dcmImage, QPixmap &pixmap) { BITMAPFILEHEADER lpfh; BITMAPINFOHEADER lpih; RGBQUAD palette[256]; memset(&lpfh, 0, sizeof(BITMAPFILEHEADER)); lpfh.bfType = 0x4d42; //'B''M' lpfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(palette); memset(&lpih, 0, sizeof(BITMAPINFOHEADER)); lpih.biSize = sizeof(BITMAPINFOHEADER); lpih.biWidth = dcmImage.getWidth(); lpih.biHeight = dcmImage.getHeight(); lpih.biCompression = BI_RGB; lpih.biBitCount = 8; lpih.biPlanes = 1; memset(palette, 0, sizeof(palette)); for (int i = 0; i < 256; ++i) { palette[i].rgbBlue = i; palette[i].rgbGreen = i; palette[i].rgbRed = i; } void *pDIB = NULL; int size = dcmImage.createWindowsDIB(pDIB, 0, 0, 8, 1, 1); //lpih.biSizeImage = size; lpfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + sizeof(palette) + size; QByteArray bmp; bmp.append((char*)&lpfh, sizeof(BITMAPFILEHEADER)); bmp.append((char*)&lpih, sizeof(BITMAPINFOHEADER)); bmp.append((char*)palette, sizeof(palette)); bmp.append((char*)pDIB, size); delete pDIB; return pixmap.loadFromData(bmp); }
DicomImage* ImageInstance::createClippedImage(const QRect &rect, int angle, bool hflip, bool vflip, bool inverted) { DicomImage *image; if (rawType) { image = rawImage; if (!image) return image; } else image = dcmImage; int ret = 1; Uint16 pvalue = image->getPhotometricInterpretation()==EPI_Monochrome1?65535:0; DicomImage *newImage = image->createClippedImage(rect.left(), rect.top(), rect.width(), rect.height(), pvalue); if (newImage) { if (ret && angle) ret = newImage->rotateImage(angle%360); if (ret && hflip) ret = newImage->flipImage(1, 0); if (ret && vflip) ret = newImage->flipImage(0, 1); if (ret && inverted) ret = newImage->setPolarity(EPP_Reverse); if (!ret) { delete newImage; newImage = 0; } } return newImage; }
void QtDcmManager::makePreview ( const QString &filename ) { DcmRLEDecoderRegistration::registerCodecs ( OFFalse, OFFalse ); DJDecoderRegistration::registerCodecs ( EDC_photometricInterpretation, EUC_default, EPC_default, OFFalse ); DcmFileFormat file; file.loadFile ( filename.toLatin1().data() ); DcmDataset * dset = file.getDataset(); DicomImage* dcimage = new DicomImage ( dset, file.getDataset()->getOriginalXfer(), CIF_MayDetachPixelData ); if ( dcimage != NULL ) { dcimage->setNoDisplayFunction(); dcimage->hideAllOverlays(); dcimage->setNoVoiTransformation(); if ( dcimage->getStatus() == EIS_Normal ) { Uint32 *pixelData = ( Uint32 * ) ( dcimage->getOutputData ( 32 /* bits per sample */ ) ); if ( pixelData != NULL ) { Uint8 *colored = new Uint8[dcimage->getWidth() * dcimage->getHeight() * 4]; //4 * dcimage->getWidth() * dcimage->getHeight() matrix Uint8 *col = colored; Uint32 *p = pixelData; //get the highest values for RGBA, then use them to scale the pixel luminosity Uint32 p_max = 0; #ifdef WIN32 Uint32 p_min = UINT_LEAST32_MAX; #else Uint32 p_min = std::numeric_limits<Uint32>::max(); #endif for ( unsigned i = 0; i < dcimage->getWidth(); ++i ) { for ( unsigned j = 0; j < dcimage->getHeight(); ++j, ++p ) { if ( *p > p_max ) { p_max = *p; } if ( *p < p_min ) { p_min = *p; } } } double a = 4294967295.f / ( ( double ) p_max - ( double ) p_min ); //re-initialize 'col' p = pixelData; //copy the pixels in our QImage for ( unsigned i = 0; i < dcimage->getWidth(); ++i ) { for ( unsigned j = 0; j < dcimage->getHeight(); ++j, ++p ) { *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = ( Uint8 ) ( ( 255.f / 4294967295.f ) * ( a * ( ( double ) ( *p ) - ( double ) p_min ) ) ); ++col; *col = 255; ++col; } } QImage image ( colored, dcimage->getWidth(), dcimage->getHeight(), QImage::Format_ARGB32 ); if ( d->previewWidget ) { d->previewWidget->imageLabel->setPixmap ( QPixmap::fromImage ( image.scaled ( 130,130 ), Qt::AutoColor ) ); } delete[] colored; } } delete dcimage; } DcmRLEDecoderRegistration::cleanup(); DJDecoderRegistration::cleanup(); }
Dose::Dose( RTDcmtkDicomInterface* rtDoseDicom, Plan* rtPlan) { d = new DoseData(); d->m_dcmGeometry = vtkSmartPointer<DCMGeometry>::New(); d->m_resampledDoseCuboid = NULL; d->m_resampled_dcm_geometry = NULL; DcmItem *ditem = NULL; const char * refPlanUID = NULL; this->frameRefUID = string(rtDoseDicom->Get_FRAME_OF_REFER_UID()); this->sopUID = string(rtDoseDicom->Get_SOP_INSTANCE_UID()); this->studyUID = string(rtDoseDicom->Get_STUDY_INSTANCE_UID()); this->seriesUID = string(rtDoseDicom->Get_SERIES_INSTANCE_UID()); this->height = rtDoseDicom->Get_ROW(); this->width = rtDoseDicom->Get_COLOUMN(); double image_orientation[6] = { 0, 0, 0, 0, 0, 0 }; string imageOrientation = string(rtDoseDicom->Get_IMAGE_ORIENTATION()); vector<string> _imageOrientation; tokenize(imageOrientation, _imageOrientation, "\\", true); for (int i = 0; i<_imageOrientation.size(); i++) { image_orientation[i] = convert_to_double(_imageOrientation.at(i).c_str()); } double xorient[3] = { image_orientation[0], image_orientation[1], image_orientation [2]}; double yorient[3] = { image_orientation[3], image_orientation[4], image_orientation [5]}; double firstImagePosition[3] = { 0, 0, 0}; double lastImagePosition[3] = { 0, 0, 0}; string imagePosition = string(rtDoseDicom->Get_IMAGE_POSITION()); vector<string> _imagePosition; tokenize(imagePosition, _imagePosition, "\\", true); for (int i = 0; i<_imagePosition.size(); i++) { firstImagePosition[i] = convert_to_double(_imagePosition.at(i).c_str()); lastImagePosition[i] = convert_to_double(_imagePosition.at(i).c_str()); } rtDoseDicom->getMinMaxPixelValue(this->minDosePixelValue, this->maxDosePixelValue);// MinMax pixel value this->doseGridScaling = convert_to_double(rtDoseDicom->Get_DOSEGRID_SCALING()); OFString _gridFrameOffsetVector; vector<string> temp; if (rtDoseDicom->dataset->findAndGetOFStringArray(DCM_GridFrameOffsetVector, _gridFrameOffsetVector).bad()) { isMultiframe = false; // return; } else { isMultiframe = true; tokenize(_gridFrameOffsetVector.c_str(), temp, "\\", true); // Convert offset vector points from string to float and store permanently. for (int i = 0; i<temp.size(); i++) { this->doseGridOffsetVector.push_back(atof(temp.at(i).c_str())); } } if (isMultiframe) lastImagePosition[2] += doseGridOffsetVector.at(doseGridOffsetVector.size() - 1); else lastImagePosition[2] += 0; double spacing[3] = { 0, 0, 0 }; const char* _pixelSpacing = rtDoseDicom->Get_PIXEL_SPACING(); vector<string> temp1; tokenize(_pixelSpacing, temp1, "\\", true); spacing[0] = convert_to_double(temp1.at(0).c_str()); spacing[1] = convert_to_double(temp1.at(1).c_str()); if (isMultiframe) { spacing[2] = this->doseGridOffsetVector.at(1) - this->doseGridOffsetVector.at(0);// hardcoded. } else { //this->pixelSpacing[0] = 0; //this->pixelSpacing[1] = 0; spacing[2] = 0; } int numberOfFrames = convert_to_int(rtDoseDicom->Get_NO_OF_FRAMES()); int dim[3] = { this->width, this->height, numberOfFrames }; d->m_dcmGeometry->SetImageGeometry(firstImagePosition, spacing, dim, xorient, yorient); //Populate frame wise pixel data in map<int,void*> framePixelData; int noOfBytes = rtDoseDicom->Get_BITS_ALLOCATED() / 8; DJDecoderRegistration::registerCodecs(); DcmRLEDecoderRegistration::registerCodecs(); DicomImage * dicomImage = new DicomImage(&rtDoseDicom->file_format, rtDoseDicom->file_format.getDataset()->getOriginalXfer(), CIF_UsePartialAccessToPixelData, 0, 1 /* fcount */); DJDecoderRegistration::cleanup(); DcmRLEDecoderRegistration::cleanup(); do{ const DiPixel* diPixel = dicomImage->getInterData(); doseFrameData* dfData = new doseFrameData(); dfData->frameNumber = dicomImage->getFirstFrame(); dfData->cols = rtDoseDicom->Get_COLOUMN(); dfData->rows = rtDoseDicom->Get_ROW(); // create a vtkImage vtkImageData* image = vtkImageData::New(); image->SetDimensions(dfData->cols, dfData->rows, 1); image->SetSpacing(spacing[0], spacing[1], 1); image->Initialize(); vtkDataArray* scalars = 0; switch (diPixel->getRepresentation()) { case EPR_Uint8: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(U8DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(U8DataType)); dfData->ORG_DicomDataType = TYPE_U8Data;*/ scalars = vtkUnsignedCharArray::New(); ((vtkUnsignedCharArray*)(scalars))->SetArray((unsigned char*)diPixel->getData(), diPixel->getCount(), 1); break; case EPR_Sint8: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(S8DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(S8DataType)); dfData->ORG_DicomDataType = TYPE_S8Data;*/ scalars = vtkSignedCharArray::New(); ((vtkSignedCharArray*)(scalars))->SetArray((signed char*)diPixel->getData(), diPixel->getCount(), 1); break; case EPR_Uint16: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(U16DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(U16DataType)); dfData->ORG_DicomDataType = TYPE_U16Data;*/ scalars = vtkUnsignedShortArray::New(); ((vtkUnsignedShortArray*)(scalars))->SetArray((unsigned short*)diPixel->getData(), diPixel->getCount(), 1); break; case EPR_Sint16: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(S16DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(S16DataType)); dfData->ORG_DicomDataType = TYPE_S16Data;*/ scalars = vtkShortArray::New(); ((vtkShortArray*)(scalars))->SetArray((short*)diPixel->getData(), diPixel->getCount(), 1); break; case EPR_Uint32: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(U32DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(U32DataType)); dfData->ORG_DicomDataType = TYPE_U32Data;*/ scalars = vtkUnsignedIntArray::New(); ((vtkUnsignedIntArray*)(scalars))->SetArray((unsigned int*)diPixel->getData(), diPixel->getCount(), 1); break; case EPR_Sint32: /*dfData->ORG_pixelData = calloc(diPixel->getCount(),sizeof(S32DataType)); memcpy(dfData->ORG_pixelData,diPixel->getData(),diPixel->getCount()*sizeof(S32DataType)); dfData->ORG_DicomDataType = TYPE_S32Data;*/ scalars = vtkIntArray::New(); ((vtkIntArray*)(scalars))->SetArray((int*)diPixel->getData(), diPixel->getCount(), 1); break; default: RAD_LOG_CRITICAL("DCMTK EP_Representation type:" << diPixel->getRepresentation() << " not supported"); } scalars->SetNumberOfComponents(1); image->SetDimensions(dfData->cols, dfData->rows, 1); image->SetSpacing(spacing[0], spacing[1], 1.0); image->GetPointData()->SetScalars(scalars); image->GetPointData()->GetScalars()->SetName("DICOMImage"); //image->Update(); double bounds[6]; image->GetBounds(bounds); // type cast all images to unsigned int32 vtkImageCast* imageCast = vtkImageCast::New(); imageCast->SetInputData(image); imageCast->SetOutputScalarTypeToFloat(); imageCast->Update(); dfData->pixelData = calloc(diPixel->getCount(), sizeof(U32DataType)); dfData->dicomDataType = TYPE_U32Data; RAD_LOG_INFO("MEMCPY pixel data for frame:" << dicomImage->getFirstFrame()) memcpy(dfData->pixelData, imageCast->GetOutput()->GetPointData()->GetScalars()->GetVoidPointer(0), imageCast->GetOutput()->GetPointData()->GetScalars()->GetSize()*sizeof(float)); imageCast->Delete(); scalars->Delete(); image->Delete(); this->allFrameDoseData.push_back(dfData); } while (dicomImage->processNextFrames()); /// compute cuboid // get first dose frame data doseFrameData* dfData = allFrameDoseData.at(0); // create VTK Cuboid int dimension[3] = { dfData->cols, dfData->rows, allFrameDoseData.size() }; long dicomSliceSize = dimension[0] * dimension[1]; long dicomDataSize = dimension[0] * dimension[1] * dimension[2]; long dicomDataIdx = dicomSliceSize; void* dicomData = rad_get_memory(dicomDataSize * sizeof(float)); #ifdef ULTA for (int i = allFrameDoseData.size() - 1; i >= 0; i--) #else for (int i = 0;i< allFrameDoseData.size();i++) #endif { float* dicomData2 = static_cast<float*>(dicomData); dicomData2 += dicomDataSize; memcpy(dicomData2 - dicomDataIdx, allFrameDoseData.at(i)->pixelData, dicomSliceSize*sizeof(float)); dicomDataIdx += dicomSliceSize; } vtkDataArray* scalars = 0; scalars = vtkFloatArray::New(); ((vtkFloatArray*)(scalars))->SetArray((float*)dicomData, dicomDataSize, 1); scalars->SetNumberOfComponents(1); d->m_doseCuboid = vtkImageData::New(); d->m_doseCuboid->SetDimensions(dimension); d->m_doseCuboid->SetSpacing(spacing); //double lip[3] = { 0, 0, 0 }; //d->m_dcmGeometry->GetLastImagePosition(lip); //d->m_doseCuboid->SetOrigin(firstImagePosition); d->m_doseCuboid->GetPointData()->SetScalars(scalars); d->m_doseCuboid->GetPointData()->GetScalars()->SetName("Dose Cuboid"); d->m_doseCuboid->Modified(); rxDose = rtPlan->getTargetPrescribedDose(); int dosemax = int(this->maxDosePixelValue * this->doseGridScaling * 10000 / rxDose); // ISODOSE LEVEL(s) READY this->isodoses.push_back(new isodose(dosemax, 120, 0, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(102, 170, 0, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(100, 238, 69, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(98, 255, 65, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(95, 255, 255, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(90, 0, 255, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(80, 0, 139, 0, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(70, 0, 255, 255, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(50, 0, 0, 255, "", false, 0, 0, "Built-In")); this->isodoses.push_back(new isodose(30, 0, 0, 128, "", false, 0, 0, "Built-In")); // Calculate cGy Value and append to names. for (int i = 0; i<this->isodoses.size(); i++) { isodose* iso = this->isodoses.at(i); iso->cGyValue = (int)(iso->level * rxDose / 100); iso->name.append(convert_to_string(iso->level)); iso->name.append("% - "); iso->name.append(convert_to_string(iso->cGyValue)); iso->name.append(" cGy"); iso->pixelIntensity = iso->level * rxDose / (this->doseGridScaling * 10000); } // load DV data DcmItem *dvhItem = NULL; signed long dvhCount = 0; while (rtDoseDicom->dataset->findAndGetSequenceItem(DCM_DVHSequence, dvhItem, dvhCount++).good()) { DVH* dh = new DVH(); DcmItem *dvhRefROISequenceItem = NULL; // ROI Number const char * RoiNumber = NULL; if (dvhItem->findAndGetSequenceItem(DCM_DVHReferencedROISequence, dvhRefROISequenceItem, 0).good()) { OFCondition status = dvhItem->findAndGetString(DCM_ReferencedROINumber, RoiNumber, true); dh->setROINumber(convert_to_uint(RoiNumber)); } // DVH Data string fNm = "D:\\DVH_DICOM_"; fNm.append(convert_to_string(dvhCount)); fNm.append(".csv"); //ofstream Morison_File(fNm.c_str()); const char * dvhdata = NULL; dvhItem->findAndGetString(DCM_DVHData, dvhdata); vector<string> dvhdataListTemp; tokenize(dvhdata, dvhdataListTemp, "\\"); for (int i = 0; i < dvhdataListTemp.size(); i++) { i++; string volume = dvhdataListTemp.at(i); if (0 > int(atof(volume.c_str()))) volume = "0"; dh->dvhDataList.push_back(convert_to_double(volume.c_str())); // Morison_File << volume.c_str() << endl; } //Morison_File.close(); //convert volume information in dvhDataList from abosulte to percentage. dh->setMaxDVHValue(*std::max_element(dh->dvhDataList.begin(), dh->dvhDataList.end())); /*std::transform(dh->dvhDataList.begin(), dh->dvhDataList.end(), dh->dvhDataList.begin(), std::bind2nd(std::divides<double>(), dh->getMaxDVHValue())); std::transform(dh->dvhDataList.begin(), dh->dvhDataList.end(), dh->dvhDataList.begin(), std::bind2nd(std::multiplies<double>(), 100));*/ // DVH Mini Dose const char * dvhMinDose = NULL; if (dvhItem->findAndGetString(DCM_DVHMinimumDose, dvhMinDose).good()) dh->setDVHMiniDose(convert_to_double(dvhMinDose)); //DVH Max Dose const char * dvhMaxDose = NULL; if (dvhItem->findAndGetString(DCM_DVHMaximumDose, dvhMaxDose).good()) dh->setDVHMaxDose(convert_to_double(dvhMaxDose)); //DVH Mean Dose const char * dvhMeanDose = NULL; if (dvhItem->findAndGetString(DCM_DVHMeanDose, dvhMeanDose).good()) dh->setDVHMeanDose(convert_to_double(dvhMeanDose)); // Structureset ref SOPUID DcmItem *dvhRefStructureSet = NULL; const char * structSetRefSOPUID = NULL; if (rtDoseDicom->dataset->findAndGetSequenceItem(DCM_ReferencedStructureSetSequence, dvhRefStructureSet).good()) { if (dvhRefStructureSet->findAndGetString(DCM_ReferencedSOPInstanceUID, structSetRefSOPUID, true).good()) dh->setStrucSetRefSopUID(string(structSetRefSOPUID)); } this->dh.push_back(dh); } }
int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { // args string dicomStem(argc > 1 ? argv[1] : "/data/subjects/xc_ferro/TrioTim-35115-20070929-151440-250000/250000"); int series = argc > 2 ? atoi(argv[2]) : 10; int numImgs = argc > 3 ? atoi(argv[3]) : 248; long tr = 1000*(argc > 4 ? atof(argv[4]) : 2000); int port = argc > 5 ? atoi(argv[5]) : 15000; string host(argc > 6 ? argv[6] : "localhost"); cout << "1 using dicomStem=" << dicomStem << endl; cout << "2 using series=" << series << endl; cout << "3 using numImgs=" << numImgs << endl; cout << "4 using tr=" << tr << endl; cout << "5 using port=" << port << endl; cout << "6 using host=" << host << endl; // Local server address. ACE_INET_Addr my_addr (port, host.c_str()); // Data transfer object. ACE_SOCK_Stream stream; // Initialize the connector. ACE_SOCK_Connector connector; // keep making new connections while we havent sent the whole series DicomImage *image; for(int i = 0; i < numImgs && (image = loadNextInSeries(dicomStem,series)) != NULL && !connector.connect (stream, my_addr); i++) { cout << "made connection, loading image" << endl; image->setMinMaxWindow(); unsigned short *upixelData = (unsigned short*)(image->getOutputData(16 /* bits */)); RtExternalImageInfo *ei = new RtExternalImageInfo(); ei->lImageDataLength = image->getOutputDataSize(); ei->lNumberOfPixels = ei->lImageDataLength/2; ei->bIsMoCo = true; ei->iNoOfImagesInMosaic = 32; ei->iMosaicGridSize = 6; ei->nCol = image->getHeight()/ei->iMosaicGridSize; ei->nLin = image->getWidth()/ei->iMosaicGridSize; // ei->nCol = 64; // ei->nLin = 64; ei->dThick = 3.5; ei->dPosSag = 2.50517; ei->dPosCor = -29.9335; ei->dPosTra = -75.1856; ei->dNorSag = -0.00637429; ei->dNorCor = 0.337923; ei->dNorTra = 0.941152; ei->dRowSag = 0.99998; ei->dRowCor = 0.00194039; ei->dRowTra = 0.00607602; ei->dColSag = 0.000227022; ei->dColCor = 0.941172; ei->dColTra = -0.337928; ei->iAcquisitionNumber = i+1; cout << "sending img " << ei->iAcquisitionNumber << endl; char *data = new char[ei->iSizeOfRtExternalImageInfo]; data = ei->convertToScannerDataArray(); cout << "sending info of size " << ei->iSizeOfRtExternalImageInfo << endl; stream.send_n (data, ei->iSizeOfRtExternalImageInfo); delete data; cout << "sending img of size " << ei->lImageDataLength << endl; // shorten to 12 bits short *pixelData = (short*) malloc(image->getOutputDataSize()); for(int i = 0; i < ei->lImageDataLength/2; i++) { pixelData[i] = upixelData[i]/16; } stream.send_n (pixelData, ei->lImageDataLength); usleep(tr); stream.close(); delete ei; delete image; free(pixelData); } return 0; }
//************************************ // Method: ReadImageDataSet // FullName: CDcmMerger::ReadImageDataSet // Access: public // Returns: int // Qualifier: // Parameter: CImageDataSet * out_pImgDataSet // Purpose: //************************************ int CDcmMerger::ReadImageDataSet( CImageDataSet* out_pImgDataSet ) { //check validation of param ASSERT(out_pImgDataSet != NULL); if (out_pImgDataSet == NULL)return SV_MEMORY_ERR; if ((m_ImageList.GetCount() <= 0) || (m_FileList.GetCount() <= 0)) return SV_FILEIO_ERROR; int retcode = SV_NORMAL; //Get size of frame DicomImage* pDcmImage = NULL; POSITION pos = NULL; INT nWidth = 0; INT nHeight = 0; INT nNumberOfFrame = 0; ULONG nSizeOfDataSet = 0; UINT nSizeOfFrame = 0; pos = m_ImageList.FindIndex(0); pDcmImage = m_ImageList.GetAt(pos); nWidth = pDcmImage->getWidth(); nHeight = pDcmImage->getHeight(); //Count number of frame and check size of all frame. for (INT i=0; i< m_ImageList.GetCount(); i++) { pos = NULL; pos = m_ImageList.FindIndex(i); if(pos != NULL) { pDcmImage = m_ImageList.GetAt(pos); if ((nWidth != pDcmImage->getWidth())|| (nHeight != pDcmImage->getHeight())) { retcode = SV_UNSUPPORT_FORMAT; } else { nNumberOfFrame += pDcmImage->getFrameCount(); } } else { retcode = SV_SYSTEM_ERR; } if (retcode != SV_NORMAL) break; } //if all frame have the same size -> allocate memory for the dataset if (retcode == SV_NORMAL) { out_pImgDataSet->m_tSize.ndx = nWidth; out_pImgDataSet->m_tSize.ndy = nHeight; out_pImgDataSet->m_tSize.ndz = nNumberOfFrame; nSizeOfDataSet = out_pImgDataSet->m_tSize.ndx * out_pImgDataSet->m_tSize.ndy * out_pImgDataSet->m_tSize.ndz; nSizeOfFrame = pDcmImage->getOutputDataSize(SV_DCM_OUTPUTBITS); ASSERT((nSizeOfFrame * nNumberOfFrame) == nSizeOfDataSet); retcode = out_pImgDataSet->PrepareBuffer(nSizeOfDataSet); } //Copy data from DICOM file to the dataset uchar* pBuff = out_pImgDataSet->GetDataBuff(); POSITION pos1 = NULL; for (INT i=0; i< m_ImageList.GetCount(); i++) { pos1 = NULL; pos1 = m_ImageList.FindIndex(i); if(pos1 != NULL) { pDcmImage = m_ImageList.GetAt(pos1); for (INT j=0; j < pDcmImage->getFrameCount(); j++) { BOOL sts = pDcmImage->getOutputData(pBuff, nSizeOfFrame,SV_DCM_OUTPUTBITS,j); if (!sts) retcode = SV_FILEIO_ERROR; else pBuff += nSizeOfFrame; if (retcode != SV_NORMAL) break; } } else retcode = SV_SYSTEM_ERR; if (retcode != SV_NORMAL) break; } return retcode; }
//************************************ // Method: Open // FullName: CDcmMerger::Open // Access: public // Returns: int // Qualifier: // Parameter: CStringList * in_pFileList // Purpose: //************************************ int CDcmMerger::Open(CStringList* in_pFileList) { int retcode = SV_NORMAL; for (INT i = 0; i< in_pFileList->GetCount(); i++) { POSITION pos = NULL; pos = in_pFileList->FindIndex(i); if(pos != NULL) { CString sFileName = in_pFileList->GetAt(pos); char* pzTempName; //Convert to ANSI code if(CUtility::UnicodeToAnsi(sFileName,&pzTempName) != ERROR_SUCCESS) retcode = SV_SYSTEM_ERR; //Create DICOM file access object DcmFileFormat* pDcmFile = NULL; DicomImage* pDcmImage = NULL; //*********Create file object pDcmFile = new DcmFileFormat(); if (pDcmFile == NULL) retcode = SV_MEMORY_ERR; //Load file E_TransferSyntax xfer; if(retcode == SV_NORMAL) { OFCondition cond = pDcmFile->loadFile(pzTempName, EXS_Unknown, EGL_withoutGL, DCM_MaxReadLength, ERM_autoDetect); if (cond.bad()) retcode = SV_FILEIO_ERROR; else xfer = pDcmFile->getDataset()->getOriginalXfer(); } OFCmdUnsignedInt opt_frame = 0; //default: start from first frame OFCmdUnsignedInt opt_frameCount = 0; //default: process all frame if(retcode == SV_NORMAL) { //*********Create image object pDcmImage = new DicomImage(pDcmFile, xfer, CIF_AcrNemaCompatibility, opt_frame, opt_frameCount); if (pDcmImage == NULL) retcode = SV_MEMORY_ERR; else if (pDcmImage->getStatus() != EIS_Normal) retcode = SV_UNSUPPORT_FORMAT; } if(retcode == SV_NORMAL) { // VOI LUT processing [1/31/2009 QUYPS] pDcmImage->setMinMaxWindow(); //Add to list m_FileList.AddTail(pDcmFile); m_ImageList.AddTail(pDcmImage); } else { delete pDcmFile; delete pDcmImage; } //Release memory delete[] pzTempName; } else { retcode = SV_SYSTEM_ERR; } //if error occur, escape from loop if (retcode != SV_NORMAL) break; } return retcode; }
// ------------------------------------------------------------------------- void ctkDICOMDatasetView::addImage( DicomImage & dcmImage, bool defaultIntensity ) { Q_D(ctkDICOMDatasetView); QImage image; // Check whether we have a valid image EI_Status result = dcmImage.getStatus(); if (result != EIS_Normal) { logger.error(QString("Rendering of DICOM image failed for thumbnail failed: ") + DicomImage::getString(result)); return; } // Select first window defined in image. If none, compute min/max window as best guess. // Only relevant for monochrome if (d->AutoWindowLevel) { if (dcmImage.isMonochrome()) { if (defaultIntensity && dcmImage.getWindowCount() > 0) { dcmImage.setWindow(0); } else { dcmImage.setMinMaxWindow(OFTrue /* ignore extreme values */); dcmImage.getWindow(d->DicomIntensityLevel, d->DicomIntensityWindow); } } } else { dcmImage.setWindow(d->DicomIntensityLevel, d->DicomIntensityWindow); } /* get image extension and prepare image header */ const unsigned long width = dcmImage.getWidth(); const unsigned long height = dcmImage.getHeight(); unsigned long offset = 0; unsigned long length = 0; QString header; if (dcmImage.isMonochrome()) { // write PGM header (binary monochrome image format) header = QString("P5 %1 %2 255\n").arg(width).arg(height); offset = header.length(); length = width * height + offset; } else { // write PPM header (binary color image format) header = QString("P6 %1 %2 255\n").arg(width).arg(height); offset = header.length(); length = width * height * 3 /* RGB */ + offset; } /* create output buffer for DicomImage class */ QByteArray buffer; /* copy header to output buffer and resize it for pixel data */ buffer.append(header); buffer.resize(length); /* render pixel data to buffer */ if (dcmImage.getOutputData(static_cast<void *>(buffer.data() + offset), length - offset, 8, 0)) { if (!image.loadFromData( buffer )) { logger.error("QImage couldn't created"); } } this->addImage(image); }
int DicomImageSet::insertFileItem(IXMLDOMDocument *pDom, IXMLDOMNode * pRoot, const QString &folderName, const QString &fileName) { DicomImage * dicomImage = new DicomImage (); if (!dicomImage->readHeader((QDir(folderName).absoluteFilePath(fileName)).toStdString().c_str())) { //fail to resolve header information return 0; } int nElement; char * patientsName = dicomImage->getCharTag(DicomImage::TAG_PATIENTS_NAME, nElement); char * patientsId = dicomImage->getCharTag(DicomImage::TAG_PATIENT_ID, nElement); char * protocolName = dicomImage->getCharTag(DicomImage::TAG_PROTOCOL_NAME, nElement); double * pInstanceNumber = dicomImage->getNumericTag(DicomImage::TAG_INSTANCE_NUMBER, nElement); double * pAcquisitionNumber = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_NUMBER, nElement); double * pAcquisitionDate = dicomImage->getNumericTag(DicomImage::TAG_ACQUISITION_DATE, nElement); int instanceNumber = pInstanceNumber?(int)pInstanceNumber[0]:-1; int acquisitionNumber = pAcquisitionNumber?(int)pAcquisitionNumber[0]:-1; int acquisitionDate = pAcquisitionDate?(int)pAcquisitionDate[0]:0; IXMLDOMNode * pParent = findParentNode(pDom, pRoot, patientsName, patientsId, acquisitionDate, protocolName, acquisitionNumber); if (!pParent) { return 0; } HRESULT hr = S_OK; IXMLDOMElement *pNode = NULL; CHK_HR(CreateElement(pDom, L"File", &pNode)); CHK_HR(CreateAndAddAttributeNode(pDom, L"path", fileName.toStdWString().c_str(), pNode)); CHK_HR(CreateAndAddAttributeNode(pDom, L"instance_number", QString::number(instanceNumber).toStdWString().c_str(), pNode)); IXMLDOMNode * pSibling = NULL; CHK_HR(pParent->get_firstChild(&pSibling)); int sibInstanceNumber = -1; VARIANT varInstanceNumber; DOMNodeType nodeType; while (pSibling && instanceNumber >= sibInstanceNumber) { CHK_HR(pSibling->get_nodeType(&nodeType)); if(nodeType == NODE_ELEMENT) { CHK_HR(GetAttributeFromNode(pSibling, L"instance_number", &varInstanceNumber)); sibInstanceNumber = QString::fromWCharArray(_bstr_t(varInstanceNumber)).toInt(); if (instanceNumber < sibInstanceNumber) { break; } } IXMLDOMNode * tmpNode = NULL; CHK_HR(pSibling->get_nextSibling(&tmpNode)); SAFE_RELEASE(pSibling); pSibling = tmpNode; } if (pSibling) { IXMLDOMNode * tmpNode = NULL; CHK_HR(pSibling->get_previousSibling(&tmpNode)); SAFE_RELEASE(pSibling); pSibling = tmpNode; } CHK_HR(CreateAndAddTextNodeBefore(pDom, L"\n", pParent, pSibling)); CHK_HR(InsertChildToParent(pNode, pSibling, pParent)); CleanUp: SAFE_RELEASE(pNode); return 1; }