18 #include "PlusConfigure.h" 19 #include "vtkCallbackCommand.h" 20 #include "vtkChartXY.h" 21 #include "vtkCommand.h" 22 #include "vtkContextScene.h" 23 #ifdef PLUS_RENDERING_ENABLED 24 #include "vtkContextView.h" 26 #include "vtkFloatArray.h" 27 #include "vtkImageData.h" 28 #ifdef PLUS_RENDERING_ENABLED 29 #include "vtkImageViewer.h" 31 #include "vtkInformation.h" 32 #include "vtkInformationVector.h" 35 #include "vtkRenderWindow.h" 36 #include "vtkRenderWindowInteractor.h" 37 #include "vtkRenderer.h" 38 #include "vtkSmartPointer.h" 41 #include "vtkTableAlgorithm.h" 43 #include "vtkXMLUtilities.h" 44 #include "vtksys/CommandLineArguments.hxx" 51 class vtkExtractImageRow :
public vtkTableAlgorithm
54 static vtkExtractImageRow* New();
55 vtkTypeMacro(vtkExtractImageRow,vtkTableAlgorithm);
56 void PrintSelf(ostream& os, vtkIndent indent)
58 this->Superclass::PrintSelf(os, indent);
63 int FillInputPortInformation(
int port, vtkInformation* info)
67 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(),
"vtkImageData");
76 this->SetNumberOfInputPorts(1);
78 virtual ~vtkExtractImageRow()
82 int RequestData(vtkInformation* vtkNotUsed(request), vtkInformationVector** inputVector, vtkInformationVector* outputVector)
84 vtkImageData* inputImage = vtkImageData::GetData(inputVector[0]);
85 vtkInformation* outInfo = outputVector->GetInformationObject(0);
86 vtkTable* outputTable = vtkTable::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
90 LOG_ERROR(
"No input image is available");
95 if (outputTable->GetColumnByName(
"wavelength")==NULL)
97 vtkSmartPointer<vtkFloatArray> arrXnew = vtkSmartPointer<vtkFloatArray>::New();
98 arrXnew->SetName(
"wavelength");
99 outputTable->AddColumn(arrXnew);
101 if (outputTable->GetColumnByName(
"Intensity")==NULL)
103 vtkSmartPointer<vtkFloatArray> arrRfValNew = vtkSmartPointer<vtkFloatArray>::New();
104 arrRfValNew->SetName(
"Intensity");
105 outputTable->AddColumn(arrRfValNew);
108 int rowCount=inputImage->GetDimensions()[1];
111 LOG_ERROR(
"Expected two rows in the input image, found "<<rowCount);
114 int numPoints=inputImage->GetDimensions()[0];
118 outputTable->SetNumberOfRows(numPoints);
119 if (inputImage->GetScalarType()==VTK_FLOAT)
121 float* wavelengthBuffer=reinterpret_cast<float*>(inputImage->GetScalarPointer())+wavelengthRow*numPoints;
122 float* intensityBuffer=reinterpret_cast<float*>(inputImage->GetScalarPointer())+intensityRow*numPoints;
123 for (
int i = 0;
i < numPoints; ++
i)
125 outputTable->SetValue(
i, 0, *(wavelengthBuffer++));
126 outputTable->SetValue(
i, 1, *(intensityBuffer++));
129 else if (inputImage->GetScalarType()==VTK_DOUBLE)
131 double* wavelengthBuffer=reinterpret_cast<double*>(inputImage->GetScalarPointer())+wavelengthRow*numPoints;
132 double* intensityBuffer=reinterpret_cast<double*>(inputImage->GetScalarPointer())+intensityRow*numPoints;
133 for (
int i = 0;
i < numPoints; ++
i)
135 outputTable->SetValue(
i, 0, *(wavelengthBuffer++));
136 outputTable->SetValue(
i, 1, *(intensityBuffer++));
141 LOG_ERROR(
"Plotting is only supported for float and double data");
149 vtkExtractImageRow(
const vtkExtractImageRow&);
150 void operator=(
const vtkExtractImageRow&);
155 #ifdef PLUS_RENDERING_ENABLED 157 class vtkMyPlotCallback :
public vtkCommand
160 static vtkMyPlotCallback *New() {
return new vtkMyPlotCallback; }
162 virtual void Execute(vtkObject *caller,
unsigned long eventId,
void* callData)
164 if (eventId==vtkCommand::KeyPressEvent)
166 if (m_Interactor->GetKeyCode()==
'q')
168 m_Interactor->ExitCallback();
173 m_ImageToTableAdaptor->Update();
176 m_Interactor->CreateTimer(VTKI_TIMER_UPDATE);
179 vtkRenderWindowInteractor *m_Interactor;
180 vtkContextView *m_Viewer;
181 vtkExtractImageRow *m_ImageToTableAdaptor;
189 m_ImageToTableAdaptor=NULL;
197 vtkSmartPointer<vtkContextView> view = vtkSmartPointer<vtkContextView>::New();
198 view->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
199 view->GetRenderWindow()->SetSize(400, 300);
200 vtkSmartPointer<vtkChartXY> chart = vtkSmartPointer<vtkChartXY>::New();
201 view->GetScene()->AddItem(chart);
203 vtkSmartPointer<vtkExtractImageRow> imageToTableAdaptor=vtkSmartPointer<vtkExtractImageRow>::New();
204 imageToTableAdaptor->SetInputConnection(spectrometer->GetOutputPort());
205 imageToTableAdaptor->Update();
208 vtkPlot *
line = chart->AddPlot(vtkChart::LINE);
209 line->SetInputData(imageToTableAdaptor->GetOutput(), 0, 1);
210 line->SetColor(0, 255, 0, 255);
213 vtkSmartPointer<vtkMyPlotCallback> call = vtkSmartPointer<vtkMyPlotCallback>::New();
214 call->m_Interactor=view->GetInteractor();
216 call->m_ImageToTableAdaptor=imageToTableAdaptor;
218 view->GetInteractor()->Initialize();
220 view->GetInteractor()->AddObserver(vtkCommand::TimerEvent, call);
221 view->GetInteractor()->CreateTimer(VTKI_TIMER_FIRST);
223 view->GetInteractor()->AddObserver(vtkCommand::KeyPressEvent, call);
225 view->GetInteractor()->Start();
231 class vtkMyCallback :
public vtkCommand
234 static vtkMyCallback *New() {
return new vtkMyCallback; }
236 virtual void Execute(vtkObject *caller,
unsigned long,
void*)
241 m_Interactor->CreateTimer(VTKI_TIMER_UPDATE);
244 vtkRenderWindowInteractor *m_Interactor;
245 vtkImageViewer *m_Viewer;
258 int main(
int argc,
char* argv[])
260 bool printHelp(
false);
261 bool renderingOff(
false);
262 std::string inputInstrumentName;
264 vtksys::CommandLineArguments args;
265 args.Initialize(argc, argv);
267 int verboseLevel = vtkPlusLogger::LOG_LEVEL_UNDEFINED;
269 args.AddArgument(
"--help", vtksys::CommandLineArguments::NO_ARGUMENT, &printHelp,
"Print this help.");
270 args.AddArgument(
"--instrument-name", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &inputInstrumentName,
"Name of the instrument to collect data from");
271 args.AddArgument(
"--rendering-off", vtksys::CommandLineArguments::NO_ARGUMENT, &renderingOff,
"Run test without rendering.");
272 args.AddArgument(
"--verbose", vtksys::CommandLineArguments::EQUAL_ARGUMENT, &verboseLevel,
"Verbose level 1=error only, 2=warning, 3=info, 4=debug, 5=trace)");
276 std::cerr <<
"Problem parsing arguments" << std::endl;
277 std::cout <<
"\n\nvtkPlusThorLabsVideoSourceTest help:" << args.GetHelp() << std::endl;
285 std::cout <<
"\n\nvtkPlusThorLabsVideoSourceTest help:" << args.GetHelp() << std::endl;
289 vtkSmartPointer<vtkPlusThorLabsVideoSource> spectrometer = vtkSmartPointer<vtkPlusThorLabsVideoSource>::New();
290 spectrometer->SetDeviceId(
"VideoDevice");
292 if (!inputInstrumentName.empty())
294 spectrometer->SetInstrumentName(inputInstrumentName.c_str());
297 spectrometer->CreateDefaultOutputChannel();
301 LOG_ERROR(
"Unable to connect to spectrometer" );
305 spectrometer->StartRecording();
310 LOG_DEBUG(
"Rendering disabled. Wait for just a few seconds to acquire data before exiting");
312 spectrometer->StopRecording();
313 spectrometer->Disconnect();
322 std::string firstChannelName;
323 std::string allChannelNames;
324 int numberOfVideoOutputChannels=0;
325 for(
ChannelContainerIterator it = spectrometer->GetOutputChannelsStart(); it != spectrometer->GetOutputChannelsEnd(); ++it)
327 if ((*it)->HasVideoSource())
329 if (numberOfVideoOutputChannels==0)
332 firstChannelName = (*it)->GetChannelId();
333 allChannelNames = (*it)->GetChannelId();
337 allChannelNames += std::string(
", ") + (*it)->GetChannelId();
339 numberOfVideoOutputChannels++;
342 if (numberOfVideoOutputChannels>1)
344 LOG_WARNING(
"Multiple output channels contain video data: "<<allChannelNames<<
". Only the first one ("<<firstChannelName<<
") will be displayed");
347 #ifdef PLUS_RENDERING_ENABLED 352 spectrometer->Disconnect();
vtkStandardNewMacro(vtkExtractImageRow)
void TestLinePlot(vtkPlusClarius *ClariusDevice)
int main(int argc, char *argv[])
static vtkIGSIOLogger * Instance()
ChannelContainer::iterator ChannelContainerIterator
ThorLabs compact spectrometer.