我的项目中有编译问题。我已经阅读了很多帖子,标题上有这个错误,但我无法修复它。
我收到此错误:
Error 4 error LNK2019: unresolved external symbol "public: class vtkUnstructuredGrid * __thiscall volumerendering::volume(class itk::SmartPointer<class itk::Image<unsigned short,3> >,class itk::SmartPointer<class itk::Image<int,3> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?volume@volumerendering@@QAEPAVvtkUnstructuredGrid@@V?$SmartPointer@V?$Image@G$02@itk@@@itk@@V?$SmartPointer@V?$Image@H$02@itk@@@4@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) referenced in function __catch$_main$0 a.obj
Error 5 fatal error LNK1120: 1 unresolved externals C:\Users\SERAP\Desktop\programlar\vnewb\Debug\DICOM.exe
代码如下:
a.cpp
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
#include "volumerendering.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
#include "itkNumericSeriesFileNames.h"
#include "itkPNGImageIO.h"
#include "itkTIFFImageIO.h"
#include <vtkXMLUnstructuredGridWriter.h>
// Software Guide : EndCodeSnippet
#include <list>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include<itkRGBPixel.h>
#include "itkThresholdImageFilter.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"
#include"vtkImageViewer2.h"
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSTLWriter.h>
// Software Guide : EndCodeSnippet
int main( int argc, char ** argv )
{
// Verify the number of parameters in the command line
if( argc < 6 )
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " firstSliceValue lastSliceValue outputImageFile OrjinalDicomDirectory Alanhesabı(txt)DosyasıAdı" << std::endl;
return EXIT_FAILURE;
}
typedef unsigned short PixelType;
const unsigned int Dimension = 3;
typedef itk::Image< PixelType, Dimension > ImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The image type is used as a template parameter to instantiate
// the reader and writer.
//
// \index{itk::ImageSeriesReader!Instantiation}
// \index{itk::ImageFileWriter!Instantiation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::ImageSeriesReader< ImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
const unsigned int first = atoi( argv[1] );
const unsigned int last = atoi( argv[2] );
typedef itk::NumericSeriesFileNames NameGeneratorType;
NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The filenames generator requires us to provide a pattern of text for the
// filenames, and numbers for the initial value, last value and increment to be
// used for generating the names of the files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
nameGenerator->SetSeriesFormat( "trabekuler%03d.tiff" );
nameGenerator->SetStartIndex( first );
nameGenerator->SetEndIndex( last );
nameGenerator->SetIncrementIndex( 1 );
reader->SetImageIO( itk::TIFFImageIO::New() );
//reader->SetImageIO( itk::PNGImageIO::New() );
reader->SetFileNames( nameGenerator->GetFileNames() );
reader->Update();
typedef int PixelType1;
const unsigned int Dimension1 = 3;
typedef itk::Image< PixelType1, Dimension1 > ImageType1;
typedef itk::ImageSeriesReader< ImageType1 > ReaderType1;
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
ImageIOType::Pointer gdcmIO = ImageIOType::New();
NamesGeneratorType::Pointer namesGenerator1 = NamesGeneratorType::New();
namesGenerator1->SetInputDirectory( argv[4] );
const ReaderType1::FileNamesContainer & filenames1 =
namesGenerator1->GetInputFileNames();
unsigned int numberOfFilenames1 = filenames1.size();
std::cout << numberOfFilenames1 << std::endl;
for(unsigned int fni1 = 0; fni1<numberOfFilenames1; fni1++)
{
std::cout << "filename # " << fni1 << " = ";
std::cout << filenames1[fni1] << std::endl;
}
ReaderType1::Pointer reader1 = ReaderType1::New();
reader1->SetImageIO( gdcmIO );
reader1->SetFileNames( filenames1 );
try
{
// Software Guide : BeginCodeSnippet
reader1->Update();
// Software Guide : EndCodeSnippet
}
catch (itk::ExceptionObject &excp)
{
std::cerr << "Exception thrown while writing the image" << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
ImageType1::Pointer image=reader1->GetOutput();
typedef itk::MetaDataDictionary DictionaryType;
const DictionaryType & dictionary = gdcmIO->GetMetaDataDictionary();
typedef itk::MetaDataObject< std::string > MetaDataStringType;
std::string entryId = "0010|0010";
DictionaryType::ConstIterator end = dictionary.End();
DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
if( tagItr == end )
{
std::cerr << "Tag " << entryId;
std::cerr << " not found in the DICOM header" << std::endl;
return EXIT_FAILURE;
}
MetaDataStringType::ConstPointer entryvalue =
dynamic_cast<const MetaDataStringType *>( tagItr->second.GetPointer() );
std::string filename2 = argv[5];
if( entryvalue )
{
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
std::cout << "Patient's Name (" << entryId << ") ";
std::cout << " is: " << tagvalue << std::endl;
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "Patient's Name: "<<tagvalue<<std::endl;
myfile .close();
}
else
{
std::cerr << "Entry was not of string type" << std::endl;
return EXIT_FAILURE;
}
//hacim ve alan hesabi
ImageType::SizeType si;
si=reader->GetOutput()->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image->GetSpacing();
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Areas: "<<std::endl;
myfile<< "\n"<<std::endl;
double alann=sp[1]*sp[0];
for(int k=si[2]-1;k>-1;k--)
{
int sayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(reader->GetOutput()->GetPixel(pixelIndex)==255)
{
sayii=sayii+1;
}
}
}
myfile<< "filename: "<<filenames1[k]<<" "<<"Area : "<<alann*sayii<<" mm_2"<<std::endl;
}
myfile .close();
// end hacim
volumerendering * vol = new volumerendering;
std::string filename = argv[3];
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer =
vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(filename.c_str());
writer->SetInput( vol->volume(reader->GetOutput(),image,filename2));
writer->Write();
return EXIT_SUCCESS;
}
volumerendering.cpp
#ifndef _volumerendering_cpp
#define _volumerendering_cpp
#include"volumerendering.h"
#include <vtkSmartPointer.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkVoxel.h>
#include <vtkUnstructuredGrid.h>
#include <vtkParticleReader.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPointSource.h>
#include <vtkPointData.h>
#include <vtkSTLWriter.h>
#include <vtkVertexGlyphFilter.h>
#include<vtkPolyDataWriter.h>
vtkUnstructuredGrid* volumerendering::volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt )
{
vtkUnstructuredGrid *ug = vtkUnstructuredGrid::New();
vtkSmartPointer<vtkPoints> points =vtkSmartPointer<vtkPoints>::New();
typedef itk::Image< unsigned short, 3 > ImageType;
typedef itk::Image< int, 3 > ImageType1;
ImageType::SizeType si;
si=image->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image1->GetSpacing();
// hacim vee alan hesapları
double hacim=sp[1]*sp[0]*sp[2];
//hacim ve alan hesabi son
int fr=0;
int hacimsayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
for(int k=0;k<si[2];k++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(image->GetPixel(pixelIndex)==255)
{hacimsayii=hacimsayii+1;
float a1[]={i*sp[0],j*sp[1],k*sp[2]};
float a2[]={(i+1)*sp[0],j*sp[1],k*sp[2]};
float a3[]={i*sp[0],(j+1)*sp[1],k*sp[2]};
float a4[]={(i+1)*sp[0],(j+1)*sp[1],k*sp[2]};
float a5[]={i*sp[0],j*sp[1],(k+1)*sp[2]};
float a6[]={(i+1)*sp[0],j*sp[1],(k+1)*sp[2]};
float a7[]={i*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
float a8[]={(i+1)*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
points->InsertPoint(fr,a1);
points->InsertPoint(fr+1,a2);
points->InsertPoint(fr+2,a3);
points->InsertPoint(fr+3,a4);
points->InsertPoint(fr+4,a5);
points->InsertPoint(fr+5,a6);
points->InsertPoint(fr+6,a7);
points->InsertPoint(fr+7,a8);
fr=fr+8;
}
}
}
}
std::ofstream myfile;
myfile.open(outt.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Volume "<<std::endl;
myfile<< "\n"<<std::endl;
myfile<< "Total Volume= "<<hacim*hacimsayii<<" mm_3"<<std::endl;
myfile .close();
static int ptr[8];
int tt=0;
int cti=points->GetNumberOfPoints();
for (int i=0;i<cti/8 ;i++)
{
for (int iy=0;iy<1;iy++)
{
ptr[0]=iy+tt; ptr[1]=iy+tt+1; ptr[2]=iy+tt+2; ptr[3]=iy+tt+3;
ptr[4]=iy+tt+4; ptr[5]=iy+tt+5; ptr[6]=iy+tt+6; ptr[7]=iy+tt+7;
ug->InsertNextCell(VTK_VOXEL,8,ptr);
tt=tt+8;
}
}
ug->SetPoints(points);
/* vtkSmartPointer<vtkDataSetMapper> mapper =
vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInput(ug);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start();*/
return ug;
}
#endif
volumerendering.h
#ifndef __volumerendering_h
#define __volumerendering_h
#include"vtkUnstructuredGrid.h"
#include"itkImage.h"
#include "itkImageSeriesReader.h"
class volumerendering
{
public:
vtkUnstructuredGrid* volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt );
};
#endif
感谢
答案 0 :(得分:0)
volumerendering.cpp
必须与项目一起编译。
但我没有看到任何阻止定义volumerendering::volume
的内容,因此可能是项目配置问题?
确保volumerendering.cpp
与a.cpp
同时编译。