Input : Jpeg Image
Commands:
Left Click will Draw the rectangle and select the cell enclosed.
Right Click will Draw the rectangle and zoom the cells enclosed.
Commands:
Left Click will Draw the rectangle and select the cell enclosed.
Right Click will Draw the rectangle and zoom the cells enclosed.
Steps to build:
- Create Folder name ChartTest keep below files in it.
- Create QChartwithInteraction.cpp and copy the below code
- Create CMakeLists.txt and copy the below code
- Use CMAKE.exe give path(c://ChartTest) of ChartTest in source and in Bin add bin next to it path(c://ChartTest//Bin)
- Click on Configure it will create the Bin folder in that path automatically. Provide ITK and VTK library path if it won't take automatically.
- Then again Click on Configure
- Than Click on Generate
- Now open the Bin folder and click on .sln file
- Click on BuildSolution under Build or press F7 key to Build it in Visual studio
- Now draw rectangle using Left click on Chart View you can see the selected cell value on command window.
Code:
QChartwithInteraction.cpp
//VTK
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include <vtkRenderWindowInteractor.h>
#include "vtkSmartPointer.h"
#include <vtkImageData.h>
#include <vtkJPEGReader.h>
//For chart Display
#include "vtkContextView.h"
#include "vtkContextScene.h"
#include "vtkChartXY.h"
#include "vtkPlot.h"
#include "vtkTable.h"
#include <vtkImageAccumulate.h>
#include<vtkIntArray.h>
#include<vtkImageExtractComponents.h>
#include <vtkCommand.h>
#include <vtkIdTypeArray.h>
#include <vtkSelection.h> // for selecting XY chart
#include <vtkContextMouseEvent.h>// For Mouse click translation
#include <vtkExtractSelection.h>
#include <vtkChartLegend.h>
#include <vtkAxis.h>
//Qt
#include <QApplication>
#include <QWidget>
#include <QMainWindow>
#include <QHBoxLayout>
#include "QVTKWidget.h"
#include "vtkQtTableView.h"
//------------------------
#define VTK_CREATE(type, name) \
vtkSmartPointer<type> name = vtkSmartPointer<type>::New()
class ChartCallback: public vtkCommand
{
public:
static ChartCallback *New()
{ return new ChartCallback; }
void Intialize(double * min,QVTKWidget *qvtkWidget)
{
m_min=min;
m_qvtkWidget=qvtkWidget;
}
virtual void Execute(vtkObject *caller, unsigned long eventId, void* )
{
vtkSmartPointer<vtkChartXY> View = vtkChartXY::SafeDownCast(caller);
int j =View->GetSelectionMode();
vtkSmartPointer<vtkChartLegend> leg=View->GetLegend();
j=View->GetNumberOfItems();
if(eventId==75)
{
int max=View->GetPlot(0)->GetSelection()->GetNumberOfTuples();
std::cout<<"Selected Intensity"<<endl;
for(int i=-1;i<max-1;i++)
{
double data=View->GetPlot(0)->GetSelection()->GetComponent(View->GetNumberOfPlots(),i);
data=double(m_min[0]+data);
std::cout<<data<<endl;
}
}
View->Update();
m_qvtkWidget->update();
}
public:
vtkSmartPointer<vtkExtractSelection> m_extract;
vtkSmartPointer<vtkAnnotationLink> m_link;
vtkSmartPointer<vtkSelection> m_sel;
vtkSmartPointer<vtkTable> m_table;
vtkSmartPointer<vtkAnnotationLink> link;
double *m_min;
QVTKWidget *m_qvtkWidget;
};
//---------------------------------------------------------------
int main( int argc, char * argv [] )
{
// Qt initialization
QApplication app(argc, argv);
QMainWindow mainWindow;
mainWindow.setGeometry(0, 0, 1150, 600);
// QVTK set up and initialization
QVTKWidget *qvtkWidget = new QVTKWidget(&mainWindow);
//Setting Data Path to VTK Reader
vtkSmartPointer<vtkJPEGReader> reader=vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D:\\testing_Dataset\\Data.jpg");//DataSet Path
reader->Update();
double X[2];
reader->GetOutput()->GetScalarRange(X);
//Generate Table
vtkTable * table= vtkTable::New();
vtkIntArray* arrX = vtkIntArray::New();
arrX->SetName("Intensity");
table->AddColumn(arrX);
vtkIntArray* arrC = vtkIntArray::New();
arrC->SetName("No of Pixels");
table->AddColumn(arrC);
vtkSmartPointer<vtkImageExtractComponents> extract =
vtkSmartPointer<vtkImageExtractComponents>::New();
extract->SetInput( reader->GetOutput());
extract->SetComponents( 0 );
extract->Update();
vtkSmartPointer<vtkImageAccumulate> histogram =
vtkSmartPointer<vtkImageAccumulate>::New();
histogram->SetInputConnection( extract->GetOutputPort() );
histogram->SetComponentExtent( int(X[0]),int(X[1]),0,0,0,0 );
histogram->SetComponentOrigin( 0,0,0 );
histogram->SetComponentSpacing( 1,0,0 );
histogram->SetIgnoreZero( 0 );
histogram->Update();
int x = int(X[0]);
int y = int(X[1]);
int range = y-x;
int* output = static_cast<int*>(histogram->GetOutput()->GetScalarPointer());
table->SetNumberOfRows(range+1);
for( int i = 0; i<=range+1; i++,x++)
{
table->SetValue(i,0,x);
table->SetValue(i,1,*output);
output++;
}
vtkPlot *line = 0;
//Chart Implimentation
vtkChartXY *chart = vtkChartXY::New();
vtkContextView *view=vtkContextView::New();
line = chart->AddPlot(vtkChart::BAR);
line->SetInput(table,0,1);
chart->GetAxis(vtkAxis::LEFT)->SetTitle("No of Pixel");
chart->GetAxis(vtkAxis::BOTTOM)->SetTitle("intensity");
chart->GetAxis(vtkAxis::BOTTOM)->SetGridVisible(false);
chart->GetAxis(vtkAxis::LEFT)->SetGridVisible(false);
chart->SetForceAxesToBounds(true);//start from minimum range
chart->SetBarWidthFraction(1);
//Draw Chart
chart->Update();
view->GetScene()->AddItem(chart);
// Translate the Widget Action //Left mouse click for select the chart // Right click for Zoom
chart->SetActionToButton(vtkChart::SELECT,
vtkContextMouseEvent::LEFT_BUTTON);
chart->SetActionToButton(vtkChart::ZOOM,
vtkContextMouseEvent::RIGHT_BUTTON);
//Providing Chart callback
vtkSmartPointer<ChartCallback> cbk =
vtkSmartPointer<ChartCallback>::New();
cbk->Intialize(X,qvtkWidget);
//Important:: This is for telling Callback to send signal if Chart cell will select
chart->AddObserver(vtkSelection::CELL,cbk);
//----------------------------------------------------------
#if VTK_MAJOR_VERSION <= 5
line->SetInput(table, 0, 1);
#else
line->SetInputData(table, 0, 1);
#endif
line->SetColor(0, 0.5, 255, 255);
//Setting ContexView in QvtkWidget
view->SetInteractor(qvtkWidget->GetInteractor());
qvtkWidget->SetRenderWindow(view->GetRenderWindow());
view->GetRenderWindow()->SetMultiSamples(0);
view->GetInteractor()->Initialize();
// Now lets try to add a table view
QWidget *widget = new QWidget(&mainWindow);
QHBoxLayout *layout = new QHBoxLayout(widget);
VTK_CREATE(vtkQtTableView, tableView);
tableView->SetSplitMultiComponentColumns(true);
tableView->AddRepresentationFromInput(table);
tableView->Update();
layout->addWidget(qvtkWidget, 2);
layout->addWidget(tableView->GetWidget());
mainWindow.setCentralWidget(widget);
// Now show the application and start the event loop
mainWindow.show();
return app.exec();
}
CMakeLists.txt
PROJECT (Charts)
IF(NOT VTK_BINARY_DIR)
FIND_PACKAGE(VTK REQUIRED)
IF(NOT VTK_USE_CHARTS)
MESSAGE(FATAL_ERROR "Example ${PROJECT_NAME} requires VTK_USE_CHARTS.")
ENDIF(NOT VTK_USE_CHARTS)
INCLUDE(${VTK_USE_FILE})
ENDIF(NOT VTK_BINARY_DIR)
IF(VTK_USE_QVTK)
FIND_PACKAGE(Qt4 REQUIRED)
INCLUDE(${QT_USE_FILE})
INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR})
ADD_EXECUTABLE(QChartTable QChartwithInteraction.cpp)
TARGET_LINK_LIBRARIES(QChartTable
QVTK
${QT_LIBRARIES}
vtkRendering
vtkCharts
)
ENDIF(VTK_USE_QVTK)
*NOTE: Let me know if you need any modification in it.