예제 #1
0
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;
}
예제 #2
0
	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();
	}
예제 #3
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);
}
예제 #4
0
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();
}
예제 #5
0
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;
}
예제 #6
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;
}
예제 #7
0
// -------------------------------------------------------------------------
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);
}