20 #include <QHostAddress> 21 #include "igtlOSUtil.h" 22 #include "igtlImageMessage.h" 23 #include "igtlServerSocket.h" 24 #include "vtkImageData.h" 25 #include "vtkSmartPointer.h" 26 #include "vtkMetaImageReader.h" 27 #include "vtkImageImport.h" 28 #include "vtkLookupTable.h" 29 #include "vtkImageMapToColors.h" 30 #include "vtkMetaImageWriter.h" 43 ImageStreamerSonix::ImageStreamerSonix() :
44 mEmitStatusMessage(false),
45 mLastFrameTimestamp(0.0),
46 mCurrentFrameTimestamp(0.0),
54 QString ImageStreamerSonix::getType()
59 QStringList ImageStreamerSonix::getArgumentDescription()
62 retval <<
"--ipaddress: IP address to connect to, default=127.0.0.1 (localhost)";
63 retval <<
"--imagingmode: default=2 (0 = B-mode, 2 = Color)";
64 retval <<
"--datatype: Video type, default=0x008 (4 = gray, 8 = color)";
65 retval <<
"--buffersize: Grabber buffer size, default=500";
66 retval <<
"--properties: dump image properties";
67 retval <<
"--debug: Debug output";
68 retval <<
"--delay: Delay (sec) before connecting to Sonix (first time), default=80";
72 ImageStreamerSonix::~ImageStreamerSonix()
77 mSonixGrabber->Stop();
78 std::cout <<
"Releasing Ultrasonix resources" << std::endl;
79 mSonixGrabber->ReleaseSystemResources();
84 void ImageStreamerSonix::initialize(
StringMap arguments)
86 std::cout <<
"Creating sender type Sonix" << std::endl;
93 qRegisterMetaType<Frame>(
"Frame");
95 connect(
this, SIGNAL(imageOnQueue(
int)),
this, SLOT(sendOpenIGTLinkImageSlot(
int)), Qt::QueuedConnection);
96 connect(
this, SIGNAL(statusOnQueue(
int)),
this, SLOT(sendOpenIGTLinkStatusSlot(
int)), Qt::QueuedConnection);
98 connect(
mSendTimer, SIGNAL(timeout()),
this, SLOT(initializeSonixSlot()));
103 this->initializeSonixGrabber();
106 void ImageStreamerSonix::initializeSonixSlot()
108 if(!mSonixGrabber->IsInitialized())
110 mSonixGrabber->Initialize();
115 if(!mSonixGrabber->getFreezeState() &&
similar(mLastFrameTimestamp, mCurrentFrameTimestamp, 0.001))
117 std::cout <<
"initializeSonixSlot() Got no new frame. Reinitializing..." << std::endl;
120 mSonixGrabber->Stop();
121 std::cout <<
"Releasing Ultrasonix resources" << std::endl;
122 mSonixGrabber->ReleaseSystemResources();
123 disconnect(mSonixHelper, SIGNAL(frame(Frame&)),
this, SLOT(receiveFrameSlot(Frame&)));
125 this->initializeSonixGrabber();
129 mLastFrameTimestamp = mCurrentFrameTimestamp;
133 void ImageStreamerSonix::initializeSonixGrabber()
151 bool useSharedMemory =
false;
152 if (ipaddress.contains(
"127.0.0.1"))
153 useSharedMemory =
true;
157 mSonixGrabber->setDebugOutput(
true);
159 mSonixGrabber->setDebugOutput(
false);
160 mSonixGrabber->setSonixConnectionDelay(delay);
161 mSonixGrabber->SetSonixIP(ipaddress.toStdString().c_str());
162 mSonixGrabber->SetImagingMode(imagingMode);
163 mSonixGrabber->SetAcquisitionDataType(acquisitionDataType);
164 mSonixGrabber->SetFrameBufferSize(bufferSize);
165 mSonixGrabber->setUseSharedMemory(useSharedMemory);
166 mSonixGrabber->Initialize();
174 mSonixGrabber->setSonixHelper(this->mSonixHelper);
175 connect(mSonixHelper, SIGNAL(frame(Frame&)),
this, SLOT(receiveFrameSlot(Frame&)), Qt::DirectConnection);
178 bool ImageStreamerSonix::startStreaming(
SenderPtr sender)
181 mSonixGrabber->Record();
182 mEmitStatusMessage =
true;
183 std::cout <<
"Started streaming from sonix device" << std::endl;
187 void ImageStreamerSonix::stopStreaming()
189 mSonixGrabber->Stop();
193 void ImageStreamerSonix::receiveFrameSlot(Frame& frame)
207 this->addStatusMessageToQueue(statMsg);
211 mEmitStatusMessage =
false;
214 IGTLinkImageMessage::Pointer imgMsg = convertFrame(frame);
217 this->addImageToQueue(imgMsg);
235 QString probeFile =
"C:/Program Files/Ultrasonix/Exam/config/probes.xml";
239 std::cout <<
"Failed to initialize probe xml reader" << std::endl;
242 QDomNode probeNode = reader.getProbeNode(frame.
probeName.c_str());
243 long radius = reader.getProbeParam(probeNode,
"radius") / 1000;
244 long probeLenght = reader.getProbeLenght(probeNode) / 1000;
249 double widthReductionFactor = 0.98;
253 probeWidth = probeLenght;
255 if(reader.isProbeLinear(probeNode))
260 retval->SetWidth(probeWidth);
265 retval->SetWidth(probeWidth/radius);
266 double depthStart = radius;
267 double depthStartIncreaseFactor = 1.01;
268 double depthEndReductionFactor = 0.99;
269 retval->SetDepthStart(depthStart * depthStartIncreaseFactor);
270 retval->SetDepthEnd((depthStart + frame.
mImagingDepth) * depthEndReductionFactor);
273 retval->SetDeviceName(createDeviceName().c_str());
277 std::string ImageStreamerSonix::createDeviceName()
279 std::string retval =
"Sonix[BGRX]";
283 IGTLinkImageMessage::Pointer ImageStreamerSonix::convertFrame(Frame& frame)
285 IGTLinkImageMessage::Pointer retval = IGTLinkImageMessage::New();
289 int offset[] = {0, 0, 0};
292 retval->SetDimensions(size);
296 retval->SetDeviceName(createDeviceName().c_str());
298 retval->SetSubVolume(size,offset);
299 retval->AllocateScalars();
301 igtl::TimeStamp::Pointer ts;
302 ts = igtl::TimeStamp::New();
304 ts->SetTime(seconds);
305 retval->SetTimeStamp(ts);
307 igtl::Matrix4x4 matrix;
308 matrix[0][0] = 1.0; matrix[1][0] = 0.0; matrix[2][0] = 0.0; matrix[3][0] = 0.0;
309 matrix[0][1] = 0.0; matrix[1][1] = 1.0; matrix[2][1] = 0.0; matrix[3][1] = 0.0;
310 matrix[0][2] = 0.0; matrix[1][2] = 0.0; matrix[2][2] = 1.0; matrix[3][2] = 0.0;
311 matrix[0][3] = 0.0; matrix[1][3] = 0.0; matrix[2][3] = 0.0; matrix[3][3] = 1.0;
312 retval->SetMatrix(matrix);
316 int fsize = retval->GetImageSize();
317 memcpy(retval->GetScalarPointer(), frame.
mFirstPixel, fsize);
331 void ImageStreamerSonix::sendOpenIGTLinkImageSlot(
int sendNumberOfMessages)
341 for(
int i=0; i<sendNumberOfMessages; ++i)
343 IGTLinkImageMessage::Pointer message = this->getLastImageMessageFromQueue();
347 package->mIgtLinkImageMessage = message;
353 void ImageStreamerSonix::sendOpenIGTLinkStatusSlot(
int sendNumberOfMessage)
364 for(
int i=0; i<sendNumberOfMessage; ++i)
371 package->mIgtLinkUSStatusMessage = message;
380 void ImageStreamerSonix::addImageToQueue(IGTLinkImageMessage::Pointer msg)
382 QMutexLocker sentry(&mImageMutex);
383 if(mMutexedImageMessageQueue.size() > mMaxqueueInfo)
385 mMutexedImageMessageQueue.pop_front();
389 mMutexedImageMessageQueue.push_back(msg);
390 int size = mMutexedImageMessageQueue.size();
393 emit queueInfo(size, mDroppedImages);
394 emit imageOnQueue(size);
399 IGTLinkImageMessage::Pointer ImageStreamerSonix::getLastImageMessageFromQueue()
401 QMutexLocker sentry(&mImageMutex);
402 if (mMutexedImageMessageQueue.empty())
403 return IGTLinkImageMessage::Pointer();
404 IGTLinkImageMessage::Pointer retval = mMutexedImageMessageQueue.front();
405 mMutexedImageMessageQueue.pop_front();
413 QMutexLocker sentry(&mStatusMutex);
414 if(mMutexedStatusMessageQueue.size() > mMaxqueueInfo)
416 mMutexedStatusMessageQueue.pop_front();
419 mMutexedStatusMessageQueue.push_back(msg);
420 int size = mMutexedStatusMessageQueue.size();
422 emit statusOnQueue(size);
429 QMutexLocker sentry(&mStatusMutex);
430 if (mMutexedStatusMessageQueue.empty())
433 mMutexedStatusMessageQueue.pop_front();
void setSendInterval(int milliseconds)
how often an image should be sent (in milliseconds)
double mTimestamp
Timestamp in seconds since 1/1/1970 (epoch)
Support Qt support for vtkSonixVideoSource.
US beam is emitted straight forward.
int mHeight
Height in pixels.
std::map< QString, QString > StringMap
US beam is emitted radially in a flat cone.
int mWidth
Width in pixels.
int mPixelFormat
Pixel format in OSType (FourCC)
boost::shared_ptr< struct Package > PackagePtr
bool similar(const CameraInfo &lhs, const CameraInfo &rhs, double tol)
unsigned char * mFirstPixel
Pointer to first pixel in frame.
int convertStringWithDefault(QString text, int def)
igtl::SmartPointer< Self > Pointer
boost::shared_ptr< Sender > SenderPtr
virtual void initialize(StringMap arguments)
int getSendInterval() const
how often an image should be sent (in milliseconds)
static vtkSonixVideoSource * New()
Namespace for all CustusX production code.