WordCloud
VTKExamples/Cxx/InfoVis/WordCloud
Description¶
A word cloud is a visualization of word frequency in a given text as a weighted list. It is a variation of a tag cloud.
This example creates a word cloud using vtkFreeTypeTools to render words into images. vtkImageBlend adds these images onto a final image. A vtkImageIterator compares pixels in the text image with those in the final image. If a non-background pixel exists in the final image, that word is not kept.
The example illustrates a number of std:: concepts including random numbers, regular expressions and multi_set.
Also, the kwsys CommandLineArguments used to process command line arguments.
Many parameters are exposed on the command line:
Usage: WordCloud textFileName --backgroundColorName opt Name of the color for the background(MignightBlue) --bwMask Mask image has a single channel(false). --colorDistribution opt o Distribution of random colors(.6 1.0). If wordColorName is not empty, random colors are generated with this distribution --colorScheme opt Color scheme(constant) --dpi opt Dots per inch(200) --fontFile opt Font file name(""). If fontFileName is empty, the built-in Arial font is used. --fontMultiplier opt Font multiplier(6). This final FontSize is this value * the word frequency. --gap opt Space gap of words (2). The gap is the number of spaces added to the beginning and end of each word --help Show help(false) --maskColorName opt Name of the color for the mask (black). This is the name of the color that defines the foreground of the mask. Usually black or white --maskFile opt Mask file name(""). If the mask file is specified, if will be used as the mask, otherwise a black square is used as the mask. --maxFontSize opt Maximum font size(48) --minFontSize opt Minimum font size(8) --offsetDistribution opt Range of random offsets(-size[0]/100.0 -size{1]/100.0)(-20 20). --orientationDistribution Ranges of random orientations(-20 20) --size opt opt ... Size of image(640 480) --wordColorName opt Name of the color for the words(). If the name is empty, the colorDistribution will generate random colors.
The example image was produced with these arguments:
WordCloud ${DATA}/Gettysburg.txt --dpi 150 --fontFile ${DATA}/Canterbury.ttf
and these parameters:
Cloud Parameters BackgroundColorName: MidnightBlue BWMask: false ColorDistribution: 0.6 1 ColorSchemeName: DPI: 150 FontFile: /Canterbury.ttf FontMultiplier: 6 Gap: 2 MaskColorName: black MaskFile: MinFontSize: 12 MaxFontSize: 48 OffsetDistribution: -6 4 OrientationDistribution: -20 20 Orientations: ReplacementPairs: Sizes: 640 480 StopWords: Title: WordColorName:
and produced this output:
Kept 94 words Stopped 178 words Skipped 5 words
Info
We may add a word cloud class to VTK is there is enough interest.
Question
If you have a simple question about this example contact us at VTKExamplesProject If your question is more complex and may require extended discussion, please use the VTK Discourse Forum
Code¶
WordCloud.cxx
#include <vtkSmartPointer.h> #include <vtkFreeTypeTools.h> #include <vtkImageBlend.h> #include <vtkImageIterator.h> #include <vtkImageData.h> #include <vtkTextProperty.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkRenderer.h> #include <vtkCamera.h> #include <vtkImageViewer2.h> #include <vtkImageCanvasSource2D.h> #include <vtkMath.h> #include <vtkNamedColors.h> #include <vtkColorSeries.h> #include <vtkImageReader2.h> #include <vtkImageReader2Factory.h> #include <vtkImageResize.h> #include <vtkImageExtractComponents.h> #include <vtkImageAppendComponents.h> #include <vtksys/CommandLineArguments.hxx> // stl #include <algorithm> #include <fstream> #include <functional> #include <iostream> #include <iterator> #include <map> #include <random> #include <regex> #include <set> #include <sstream> #include <string> #include <vector> namespace { // Cloud Parameters struct CloudParameters { CloudParameters() : FontFile(""), MaskFile(""), DPI(200), MaxFontSize(48), MinFontSize(12), MinFrequency(1), FontMultiplier(6), ColorSchemeName(""), BackgroundColorName("MidnightBlue"), MaskColorName("black"), BWMask(false), WordColorName(""), Gap(2), KeptCount(0) {}; void Print(ostream& os) { os << "Cloud Parameters" << std::endl; os << " BackgroundColorName: " << BackgroundColorName << std::endl; os << " BWMask: " << (BWMask ? "true" : "false") << std::endl; os << " ColorDistribution: " << ColorDistribution[0] << " " << ColorDistribution[1] << std::endl; os << " ColorSchemeName: " << ColorSchemeName << std::endl; os << " DPI: " << DPI << std::endl; os << " FontFile: " << FontFile << std::endl; os << " FontMultiplier: " << FontMultiplier << std::endl; os << " Gap: " << Gap << std::endl; os << " MaskColorName: " << MaskColorName << std::endl; os << " MaskFile: " << MaskFile << std::endl; os << " MinFontSize: " << MinFontSize << std::endl; os << " MaxFontSize: " << MaxFontSize << std::endl; os << " MinFrequency: " << MinFrequency << std::endl; os << " OffsetDistribution: " << OffsetDistribution[0] << " " << OffsetDistribution[1] << std::endl; os << " OrientationDistribution: " << OrientationDistribution[0] << " " << OrientationDistribution[1] << std::endl; os << " Orientations: "; for (auto o : Orientations) { os << o << " "; } os << std::endl; os << " ReplacementPairs: "; for (auto p = 0; p < ReplacementPairs.size(); p += 2) { os << ReplacementPairs[p] << "->" << ReplacementPairs[p + 1] << " "; } os << std::endl; os << " Sizes: " << Sizes[0] << " " << Sizes[1] << std::endl; os << " StopWords: "; for (auto s : StopWords) { os << s << " "; } os << std::endl; os << " Title: " << Title << std::endl; os << " WordColorName: " << WordColorName << std::endl; } std::vector<int> AdjustedSizes; std::string BackgroundColorName; bool BWMask; std::string ColorSchemeName; int DPI; std::string FontFile; int Gap; int KeptCount; std::string MaskColorName; std::string MaskFile; int MaxFontSize; int MinFontSize; int MinFrequency; int FontMultiplier; std::vector<double> ColorDistribution; std::vector<int> OffsetDistribution; std::vector<double> OrientationDistribution; std::vector<double> Orientations; std::vector<std::string> ReplacementPairs; std::vector<int> Sizes; std::vector<std::string> StopWords; std::string Title; std::string WordColorName; }; bool ProcessCommandLine(vtksys::CommandLineArguments &arg, CloudParameters &cloudParameters); // Declaring the type of Predicate that accepts 2 pairs and return a bool typedef std::function<bool( std::pair<std::string, int>, std::pair<std::string, int>)> Comparator; std::multiset<std::pair<std::string, int>, Comparator > FindWordsSortedByFrequency(std::string &, CloudParameters &cloudParameters); struct ExtentOffset { ExtentOffset(int _x = 0.0, int _y = 0.0) : x(_x), y(_y) {} int x,y; }; struct ArchimedesValue { ArchimedesValue(double _x = 0.0, double _y = 0.0) : x(_x), y(_y) {} double x,y; }; bool AddWordToFinal(const std::string, const int, CloudParameters &, std::mt19937 &, double orientation, std::vector<ExtentOffset> &, vtkImageBlend *, std::array<int, 6> &); void ArchimedesSpiral (std::vector<ExtentOffset>&, std::vector<int>&); void ReplaceMaskColorWithBackgroundColor(vtkImageData*, CloudParameters &); void CreateStopList(std::vector<std::string> &StopList); void ShowColorSeriesNames(ostream& os); } int main (int argc, char *argv[]) { // Process command line argumemts CloudParameters cloudParameters; vtksys::CommandLineArguments arg; arg.Initialize(argc, argv); if (!ProcessCommandLine(arg, cloudParameters)) { return EXIT_FAILURE; } // Get the file that contains the text to be converted to a word cloud char** newArgv = nullptr; int newArgc = 0; arg.GetUnusedArguments(&newArgc, &newArgv); if (newArgc < 2) { std::cout << "Usage: " << argv[0] << " textFileName " << arg.GetHelp() << std::endl; return EXIT_FAILURE; } // Open the text file std::ifstream t(newArgv[1]); std::stringstream buffer; buffer << t.rdbuf(); std::string s = buffer.str(); t.close(); // Generate a path for placement of words std::vector<ExtentOffset> offset; ArchimedesSpiral(offset, cloudParameters.Sizes); // Sort the word by frequency std::multiset<std::pair<std::string, int>, Comparator> sortedWords = FindWordsSortedByFrequency(s, cloudParameters); // Create a mask image auto colors = vtkSmartPointer<vtkNamedColors>::New(); vtkColor3ub maskColor = colors->GetColor3ub(cloudParameters.MaskColorName.c_str()); auto maskImage = vtkSmartPointer<vtkImageData>::New(); // If a mask file is not defined, create a square mask if (cloudParameters.MaskFile == "") { auto defaultMask = vtkSmartPointer<vtkImageCanvasSource2D>::New(); defaultMask->SetScalarTypeToUnsignedChar(); defaultMask->SetNumberOfScalarComponents(3); defaultMask->SetExtent(0, cloudParameters.Sizes[0] - 1, 0, cloudParameters.Sizes[1] - 1, 0, 0); defaultMask->SetDrawColor(maskColor.GetData()[0], maskColor.GetData()[1], maskColor.GetData()[2]); defaultMask->FillBox(0, cloudParameters.Sizes[0] - 1, 0, cloudParameters.Sizes[1] - 1); defaultMask->Update(); maskImage = defaultMask->GetOutput(); cloudParameters.AdjustedSizes.push_back(cloudParameters.Sizes[0]); cloudParameters.AdjustedSizes.push_back(cloudParameters.Sizes[1]); } else { // Read the mask file auto readerFactory = vtkSmartPointer<vtkImageReader2Factory>::New(); vtkSmartPointer<vtkImageReader2> reader; reader.TakeReference( readerFactory->CreateImageReader2(cloudParameters.MaskFile.c_str())); reader->SetFileName(cloudParameters.MaskFile.c_str()); reader->Update(); int dimensions[3]; reader->GetOutput()->GetDimensions(dimensions); auto resize = vtkSmartPointer<vtkImageResize>::New(); resize->SetInputData(reader->GetOutput()); resize->InterpolateOff(); double aspect = static_cast<double>(dimensions[1]) / static_cast<double>(dimensions[0]) * static_cast<double>(cloudParameters.Sizes[0]) / static_cast<double>(cloudParameters.Sizes[1]); cloudParameters.AdjustedSizes.push_back(cloudParameters.Sizes[0]); cloudParameters.AdjustedSizes.push_back(aspect * cloudParameters.Sizes[1]); resize->SetOutputDimensions(cloudParameters.AdjustedSizes[0], cloudParameters.AdjustedSizes[1], 1); if (cloudParameters.BWMask) { auto appendFilter = vtkSmartPointer<vtkImageAppendComponents>::New(); appendFilter->SetInputConnection(0, resize->GetOutputPort()); appendFilter->AddInputConnection(0, resize->GetOutputPort()); appendFilter->AddInputConnection(0, resize->GetOutputPort()); appendFilter->Update(); maskImage = appendFilter->GetOutput(); } else { auto rgbImage = vtkSmartPointer<vtkImageExtractComponents>::New(); rgbImage->SetInputConnection(resize->GetOutputPort()); rgbImage->SetComponents(0, 1, 2); rgbImage->Update(); maskImage = rgbImage->GetOutput(); } } // Create an image that will hold the final image auto final = vtkSmartPointer<vtkImageBlend>::New(); final->AddInputData(maskImage); final->SetOpacity(0, .5); final->Update(); // Try to add each word int numberSkipped = 0; int keep = 0; std::array<int, 6> extent; bool added; // Create a vector of orientations to try. std::mt19937 mt(4355412); //Standard mersenne twister engine for (auto element : sortedWords) { std::vector<double> orientations; if (cloudParameters.Orientations.size() != 0) { orientations = cloudParameters.Orientations; } else { std::uniform_real_distribution<> orientationDist( cloudParameters.OrientationDistribution[0], cloudParameters.OrientationDistribution[1]); orientations.push_back(orientationDist(mt)); } std::shuffle(std::begin(orientations), std::end(orientations), mt); for (auto o : orientations) { added = AddWordToFinal( element.first, element.second, cloudParameters, mt, o, offset, final, extent); if (added) { // std::cout << element.first << ": " << element.second << std::endl; keep++; break; } else { numberSkipped++; // std::cout << "skipped: " << element.first << ": " << element.second << std::endl; } } } std::cout << "Kept " << keep << " words" << std::endl; std::cout << "Skipped " << numberSkipped << " words" << std::endl; // If a maskFile is specified, replace the maskColor with the background color ReplaceMaskColorWithBackgroundColor(final->GetOutput(), cloudParameters); // Display the final image auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); auto imageViewer = vtkSmartPointer<vtkImageViewer2>::New(); imageViewer->SetInputData(final->GetOutput()); imageViewer->SetupInteractor(interactor); imageViewer->GetRenderer()->SetBackground(colors->GetColor3d("Wheat").GetData()); imageViewer->SetSize(cloudParameters.Sizes[0], cloudParameters.Sizes[1]); imageViewer->GetRenderer()->ResetCamera(); // Zoom in a bit vtkCamera* camera = imageViewer->GetRenderer()->GetActiveCamera(); camera->ParallelProjectionOn(); camera->SetParallelScale(cloudParameters.AdjustedSizes[0] * .4); imageViewer->GetRenderWindow()->Render(); interactor->Start(); return EXIT_SUCCESS; } namespace { std::multiset<std::pair<std::string, int>, Comparator > FindWordsSortedByFrequency(std::string &s, CloudParameters &cloudParameters) { // Make replacements // Create a stop list std::vector<std::string> stopList; CreateStopList(stopList); // Add user stop words for (auto stop : cloudParameters.StopWords) { stopList.push_back(stop); } // Drop the case of all words std::transform(s.begin(), s.end(), s.begin(), ::tolower); // Extract words std::regex wordRegex("(\\w+)"); auto wordsBegin = std::sregex_iterator(s.begin(), s.end(), wordRegex); auto wordsEnd = std::sregex_iterator(); // Store the words in a map that will contain frequencies std::map<std::string, int> wordContainer; // If a title is present add it with a high frequency if (cloudParameters.Title.length() > 0) { wordContainer[cloudParameters.Title] = 1000; } const int N = 1; int stop = 0; for (std::sregex_iterator i = wordsBegin; i != wordsEnd; ++i) { std::string matchStr = (*i).str(); // Replace words with another for (auto p = 0; p < cloudParameters.ReplacementPairs.size(); p += 2) { std::string from = cloudParameters.ReplacementPairs[p]; std::string to = cloudParameters.ReplacementPairs[p + 1]; size_t pos = 0; pos = matchStr.find(from, pos); if (matchStr.length() == from.length() && pos == 0) { matchStr.replace(pos, to.length(), to); stopList.push_back(from); } } // Skip the word if it is in the stop list or contains a digit auto it = std::find (stopList.begin(), stopList.end() - 1, matchStr); const auto digit = (*i).str().find_first_of("0123456789"); if (*it != *(stopList.end() - 1)|| digit != std::string::npos) { stop++; continue; } // Only include words that have more than N characters if (matchStr.size() > N) { // Raise the case of he first letter in the word std::transform(matchStr.begin(), matchStr.begin() + 1, matchStr.begin(), ::toupper); wordContainer[matchStr]++; } } std::cout << "Stopped " << stop << " words" << std::endl; // Defining a lambda function to compare two pairs. It will compare // two pairs using second field Comparator compFunctor = [](std::pair<std::string, int> elem1 ,std::pair<std::string, int> elem2) { if (elem1.second == elem2.second) { return elem1.first.length() > elem2.first.length(); } return elem1.second > elem2.second; }; // Declaring a multiset that will store the pairs using above comparision logic std::multiset<std::pair<std::string, int>, Comparator> setOfWords( wordContainer.begin(), wordContainer.end(), compFunctor); return setOfWords; } bool AddWordToFinal(const std::string word, const int frequency, CloudParameters &cloudParameters, std::mt19937 &mt, double orientation, std::vector<ExtentOffset> &offset, vtkImageBlend *final, std::array<int, 6> &extent) { // Skip single character words if (frequency < cloudParameters.MinFrequency) { return false; } // Create an image of the string vtkFreeTypeTools *freeType = vtkFreeTypeTools::GetInstance(); freeType->ScaleToPowerTwoOff(); // Create random distributions std::uniform_real_distribution<> colorDist( cloudParameters.ColorDistribution[0], cloudParameters.ColorDistribution[1]); bool discreteOrientations = cloudParameters.Orientations.size() != 0; // Setup a property for the strings containing fixed parameters auto colors = vtkSmartPointer<vtkNamedColors>::New(); auto textProperty = vtkSmartPointer<vtkTextProperty>::New(); if (cloudParameters.WordColorName.length() > 0) { textProperty->SetColor(colors->GetColor3d(cloudParameters.WordColorName).GetData()); } else if (cloudParameters.ColorSchemeName.length() > 0) { auto colorScheme = vtkSmartPointer<vtkColorSeries>::New(); int index = colorScheme->SetColorSchemeByName(cloudParameters.ColorSchemeName); vtkColor3ub color = colorScheme->GetColorRepeating(cloudParameters.KeptCount); if (color.Compare(colors->GetColor3ub("black"), 1) && cloudParameters.KeptCount == 0) { std::cout << "The color scheme " << cloudParameters.ColorSchemeName << " does not exist." << std::endl; ShowColorSeriesNames(std::cout); } textProperty->SetColor(color.GetRed() * 255.0, color.GetGreen() * 255.0 , color.GetBlue() * 255.0); } else { textProperty->SetColor(colorDist(mt), colorDist(mt), colorDist(mt)); } textProperty->SetVerticalJustificationToCentered(); textProperty->SetJustificationToCentered(); textProperty->SetLineOffset(4); // Check if a font file is present if (cloudParameters.FontFile.length() > 0) { textProperty->SetFontFile(cloudParameters.FontFile.c_str()); textProperty->SetFontFamily(VTK_FONT_FILE); } else { textProperty->SetFontFamilyToArial(); } // Set the font size int fontSize = cloudParameters.FontMultiplier * frequency; if (fontSize > cloudParameters.MaxFontSize) { fontSize = cloudParameters.MaxFontSize; } if (fontSize < cloudParameters.MinFontSize) { fontSize = cloudParameters.MinFontSize; } if (frequency == 1000) { fontSize *= 1.2;; } textProperty->SetFontSize(fontSize); textProperty->SetOrientation(orientation); // Add gap std::string spaces; for (int p = 0; p < cloudParameters.Gap; ++p) { spaces.push_back(' '); } // For each string, create an image and see if it overlaps with other images, // if so, skip it int accepted = 0; auto textImage = vtkSmartPointer<vtkImageData>::New(); freeType->RenderString(textProperty, spaces + word + spaces, cloudParameters.DPI, textImage.GetPointer()); // Set the extent of the text image std::array<int, 4> bb; freeType->GetBoundingBox(textProperty, spaces + word + spaces, cloudParameters.DPI, bb.data()); vtkColor3ub maskColor = colors->GetColor3ub(cloudParameters.MaskColorName.c_str()); unsigned char maskR = maskColor.GetData()[0]; unsigned char maskG = maskColor.GetData()[1]; unsigned char maskB = maskColor.GetData()[2]; std::uniform_real_distribution<> offsetDist( cloudParameters.OffsetDistribution[0], cloudParameters.OffsetDistribution[1]); for (auto it = offset.begin(); it < offset.end(); ++it) { int offsetX = (*it).x + offsetDist(mt); // add some noise to the offset int offsetY = (*it).y + offsetDist(mt); // Make sure the text image will fit on the final image if (offsetX + bb[1] - bb[0] < cloudParameters.AdjustedSizes[0] - 1 && offsetY + bb[3] - bb[2] < cloudParameters.AdjustedSizes[1] - 1 && offsetX >= 0 && offsetY >= 0) { textImage->SetExtent(offsetX, offsetX + bb[1] - bb[0], offsetY, offsetY + bb[3] - bb[2], 0, 0); auto image = vtkSmartPointer<vtkImageData>::New(); final->Update(); // Does the text image overlap with images on the final image vtkImageIterator<unsigned char> finalIt(final->GetOutput(), textImage->GetExtent()); textImage->GetExtent(extent.data()); bool good = true; while( !finalIt.IsAtEnd()) { auto finalSpan = finalIt.BeginSpan(); while(finalSpan != finalIt.EndSpan()) { unsigned char R, G, B; R = *finalSpan++; G = *finalSpan++; B = *finalSpan++; // If the pixel does not contain the background color, the word will not fit if (R != maskR && G != maskG && B != maskB) { good = false; break; } } if (!good) { break; } finalIt.NextSpan(); } if (good) { accepted++; (cloudParameters.KeptCount)++; image->DeepCopy(textImage); final->AddInputData(image); final->Update(); return true; } } } return false; } void ArchimedesSpiral(std::vector<ExtentOffset> &offset, std::vector<int> &sizes) { const int centerX = sizes[0] / 2.0; const int centerY = sizes[1] / 2.0; const std::size_t N = 10000; constexpr auto pi = 3.141592653589793238462643383279502884L; /* pi */ const double deltaAngle = pi * 20 / N; double maxX = -1000.0; double minX = 1000.0; double maxY = -1000.0; double minY = 1000.0; double range = -1000; double e = sizes[0] / sizes[1]; std::vector<ArchimedesValue> archimedes; for (std::size_t i = 0; i < N; i += 10) { double x, y; double angle = deltaAngle * i; x = e * angle * std::cos(angle); y = e * angle * std::sin(angle); archimedes.push_back(ArchimedesValue(x, y)); maxX = std::max(maxX, x); minX = std::min(minX, x); maxY = std::max(maxY, y); minY = std::min(minY, y); range = std::max(maxX - minX, maxY - minY); } double scaleX = 1.0 / range * sizes[0]; double scaleY = 1.0 / range * sizes[1]; int j = 0; for (auto it = archimedes.begin(); it < archimedes.end(); ++it) { if ((*it).y * scaleX + centerY < 0 || (*it).x * scaleX + centerX - 50 < 0) continue; offset.push_back(ExtentOffset((*it).x * scaleX + centerX - 50, (*it).y * scaleX + centerY)); } } bool ProcessCommandLine(vtksys::CommandLineArguments &arg, CloudParameters &cloudParameters) { typedef vtksys::CommandLineArguments argT; // Need this to get arguments without --'s arg.StoreUnusedArguments(true); arg.AddArgument("--backgroundColorName", argT::SPACE_ARGUMENT, &cloudParameters.BackgroundColorName, "Name of the color for the background(MignightBlue)"); arg.AddArgument("--colorDistribution", argT::MULTI_ARGUMENT, &cloudParameters.ColorDistribution, "Distribution of random colors(.6 1.0). If wordColorName is not empty, random colors are generated with this distribution"); arg.AddArgument("--colorSchemeName", argT::SPACE_ARGUMENT, &cloudParameters.ColorSchemeName, "Color scheme name()"); arg.AddArgument("--dpi", argT::SPACE_ARGUMENT, &cloudParameters.DPI, "Dots per inch(200)"); arg.AddArgument("--fontFile", argT::SPACE_ARGUMENT, &cloudParameters.FontFile, "Font file name(\"\"). If fontFileName is empty, the built-in Arial font is used."); arg.AddArgument("--fontMultiplier", argT::SPACE_ARGUMENT, &cloudParameters.FontMultiplier, "Font multiplier(6). This final FontSize is this value * the word frequency."); arg.AddArgument("--gap", argT::SPACE_ARGUMENT, &cloudParameters.Gap, "Space gap of words (2). The gap is the number of spaces added to the beginning and end of each word"); arg.AddArgument("--maskColorName", argT::SPACE_ARGUMENT, &cloudParameters.MaskColorName, "Name of the color for the mask (black). This is the name of the color that defines the foreground of the mask. Usually black or white"); arg.AddArgument("--maskFile", argT::SPACE_ARGUMENT, &cloudParameters.MaskFile, "Mask file name(\"\"). If the mask file is specified, if will be used as the mask, otherwise a black square is used as the mask."); arg.AddArgument("--minFontSize", argT::SPACE_ARGUMENT, &cloudParameters.MinFontSize, "Minimum font size(8)"); arg.AddArgument("--minFrequency", argT::SPACE_ARGUMENT, &cloudParameters.MinFrequency, "Minimum word frequency accepted(2)"); arg.AddArgument("--maxFontSize", argT::SPACE_ARGUMENT, &cloudParameters.MaxFontSize, "Maximum font size(48)"); arg.AddArgument("--offsetDistribution", argT::MULTI_ARGUMENT, &cloudParameters.OffsetDistribution, "Range of random offsets(-size[0]/100.0 -size{1]/100.0)(-20 20)."); arg.AddArgument("--orientationDistribution", argT::MULTI_ARGUMENT, &cloudParameters.OrientationDistribution, "Ranges of random orientations(-20 20)"); arg.AddArgument("--orientations", argT::MULTI_ARGUMENT, &cloudParameters.Orientations, "List of discrete orientations (). If non-empty, these will be used instead of the orientations distribution"); arg.AddArgument("--stopWords", argT::MULTI_ARGUMENT, &cloudParameters.StopWords, "User provided stop words(). These will ba added to the built-in stop list."); arg.AddArgument("--bwMask" , argT::NO_ARGUMENT, &cloudParameters.BWMask, "Mask image has a single channel(false). Mask images normally have three channels (r,g,b)."); arg.AddArgument("--size" , argT::MULTI_ARGUMENT, &cloudParameters.Sizes, "Size of image(640 480)"); arg.AddArgument("--wordColorName", argT::SPACE_ARGUMENT, &cloudParameters.WordColorName, "Name of the color for the words(). If the name is empty, the colorDistribution will generate random colors."); arg.AddArgument("--replacementPairs", argT::MULTI_ARGUMENT, &cloudParameters.ReplacementPairs, "Replace word with another word ()."); arg.AddArgument("--title", argT::SPACE_ARGUMENT, &cloudParameters.Title, "Use this word and set a high frequency()."); bool help = false; arg.AddArgument("--help" , argT::NO_ARGUMENT, &help, "Show help(false)"); arg.Parse(); if (help) { std::cout << "Usage: " << "WordCloud" << " textFileName " << arg.GetHelp() << std::endl; return false; } // Set defaults for vector arguments if (cloudParameters.ColorDistribution.size() == 0) { cloudParameters.ColorDistribution.push_back(.6); cloudParameters.ColorDistribution.push_back(1.0); } if (cloudParameters.OrientationDistribution.size() == 0) { cloudParameters.OrientationDistribution.push_back(-20); cloudParameters.OrientationDistribution.push_back(20); } if (cloudParameters.Sizes.size() == 0) { cloudParameters.Sizes.push_back(640); cloudParameters.Sizes.push_back(480); } if (cloudParameters.OffsetDistribution.size() == 0) { cloudParameters.OffsetDistribution.push_back(-cloudParameters.Sizes[0] / 100.0); cloudParameters.OffsetDistribution.push_back( cloudParameters.Sizes[1] / 100.0); } cloudParameters.Print(std::cout); return true; } void ReplaceMaskColorWithBackgroundColor(vtkImageData* finalImage, CloudParameters &cloudParameters) { auto colors = vtkSmartPointer<vtkNamedColors>::New(); vtkColor3ub maskColor = colors->GetColor3ub(cloudParameters.MaskColorName.c_str()); unsigned char maskR = maskColor.GetData()[0]; unsigned char maskG = maskColor.GetData()[1]; unsigned char maskB = maskColor.GetData()[2]; vtkColor3ub backgroundColor = colors->GetColor3ub(cloudParameters.BackgroundColorName.c_str()); unsigned char bkgR = backgroundColor.GetData()[0]; unsigned char bkgG = backgroundColor.GetData()[1]; unsigned char bkgB = backgroundColor.GetData()[2]; vtkImageIterator<unsigned char> finalIt(finalImage, finalImage->GetExtent()); while( !finalIt.IsAtEnd()) { auto finalSpan = finalIt.BeginSpan(); while(finalSpan != finalIt.EndSpan()) { unsigned char R, G, B; R = *finalSpan; G = *(finalSpan + 1); B = *(finalSpan + 2); // If the pixel does not contain the background color, the word will not fit if (R != maskR && G != maskG && B != maskB) { finalSpan += 3; continue; } else { *finalSpan = bkgR; *(finalSpan + 1) = bkgG; *(finalSpan + 2) = bkgB; } finalSpan += 3; } finalIt.NextSpan(); } } void ShowColorSeriesNames(ostream& os) { auto colorSeries = vtkSmartPointer<vtkColorSeries>::New(); os << "Valid schemes" << std::endl; for (auto i = 0; i < colorSeries->GetNumberOfColorSchemes(); ++i) { colorSeries->SetColorScheme(i); os << " " << colorSeries->GetColorSchemeName() << std::endl; } } void CreateStopList(std::vector<std::string> &stopList) { stopList.push_back("a"); stopList.push_back("able"); stopList.push_back("about"); stopList.push_back("above"); stopList.push_back("abst"); stopList.push_back("accordance"); stopList.push_back("according"); stopList.push_back("accordingly"); stopList.push_back("across"); stopList.push_back("act"); stopList.push_back("actually"); stopList.push_back("added"); stopList.push_back("adj"); stopList.push_back("affected"); stopList.push_back("affecting"); stopList.push_back("affects"); stopList.push_back("after"); stopList.push_back("afterwards"); stopList.push_back("again"); stopList.push_back("against"); stopList.push_back("ah"); stopList.push_back("all"); stopList.push_back("almost"); stopList.push_back("alone"); stopList.push_back("along"); stopList.push_back("already"); stopList.push_back("also"); stopList.push_back("although"); stopList.push_back("always"); stopList.push_back("am"); stopList.push_back("among"); stopList.push_back("amongst"); stopList.push_back("an"); stopList.push_back("and"); stopList.push_back("announce"); stopList.push_back("another"); stopList.push_back("any"); stopList.push_back("anybody"); stopList.push_back("anyhow"); stopList.push_back("anymore"); stopList.push_back("anyone"); stopList.push_back("anything"); stopList.push_back("anyway"); stopList.push_back("anyways"); stopList.push_back("anywhere"); stopList.push_back("apparently"); stopList.push_back("approximately"); stopList.push_back("are"); stopList.push_back("aren"); stopList.push_back("arent"); stopList.push_back("arise"); stopList.push_back("around"); stopList.push_back("as"); stopList.push_back("aside"); stopList.push_back("ask"); stopList.push_back("asking"); stopList.push_back("at"); stopList.push_back("auth"); stopList.push_back("available"); stopList.push_back("away"); stopList.push_back("awfully"); stopList.push_back("b"); stopList.push_back("back"); stopList.push_back("be"); stopList.push_back("became"); stopList.push_back("because"); stopList.push_back("become"); stopList.push_back("becomes"); stopList.push_back("becoming"); stopList.push_back("been"); stopList.push_back("before"); stopList.push_back("beforehand"); stopList.push_back("begin"); stopList.push_back("beginning"); stopList.push_back("beginnings"); stopList.push_back("begins"); stopList.push_back("behind"); stopList.push_back("being"); stopList.push_back("believe"); stopList.push_back("below"); stopList.push_back("beside"); stopList.push_back("besides"); stopList.push_back("between"); stopList.push_back("beyond"); stopList.push_back("biol"); stopList.push_back("both"); stopList.push_back("brief"); stopList.push_back("briefly"); stopList.push_back("but"); stopList.push_back("by"); stopList.push_back("c"); stopList.push_back("ca"); stopList.push_back("came"); stopList.push_back("can"); stopList.push_back("cannot"); stopList.push_back("can't"); stopList.push_back("cause"); stopList.push_back("causes"); stopList.push_back("certain"); stopList.push_back("certainly"); stopList.push_back("co"); stopList.push_back("com"); stopList.push_back("come"); stopList.push_back("comes"); stopList.push_back("contain"); stopList.push_back("containing"); stopList.push_back("contains"); stopList.push_back("could"); stopList.push_back("couldnt"); stopList.push_back("cum"); stopList.push_back("d"); stopList.push_back("date"); stopList.push_back("did"); stopList.push_back("didn't"); stopList.push_back("different"); stopList.push_back("do"); stopList.push_back("does"); stopList.push_back("doesn't"); stopList.push_back("doing"); stopList.push_back("done"); stopList.push_back("don't"); stopList.push_back("down"); stopList.push_back("downwards"); stopList.push_back("due"); stopList.push_back("dr"); stopList.push_back("during"); stopList.push_back("e"); stopList.push_back("each"); stopList.push_back("ed"); stopList.push_back("edu"); stopList.push_back("effect"); stopList.push_back("eg"); stopList.push_back("eight"); stopList.push_back("eighty"); stopList.push_back("either"); stopList.push_back("else"); stopList.push_back("elsewhere"); stopList.push_back("end"); stopList.push_back("ending"); stopList.push_back("enough"); stopList.push_back("especially"); stopList.push_back("et"); stopList.push_back("et-al"); stopList.push_back("etc"); stopList.push_back("even"); stopList.push_back("ever"); stopList.push_back("every"); stopList.push_back("everybody"); stopList.push_back("everyone"); stopList.push_back("everything"); stopList.push_back("everywhere"); stopList.push_back("ex"); stopList.push_back("except"); stopList.push_back("f"); stopList.push_back("far"); stopList.push_back("few"); stopList.push_back("ff"); stopList.push_back("fifth"); stopList.push_back("first"); stopList.push_back("five"); stopList.push_back("fix"); stopList.push_back("followed"); stopList.push_back("following"); stopList.push_back("follows"); stopList.push_back("for"); stopList.push_back("former"); stopList.push_back("formerly"); stopList.push_back("forth"); stopList.push_back("found"); stopList.push_back("four"); stopList.push_back("from"); stopList.push_back("further"); stopList.push_back("furthermore"); stopList.push_back("g"); stopList.push_back("gave"); stopList.push_back("get"); stopList.push_back("gets"); stopList.push_back("getting"); stopList.push_back("give"); stopList.push_back("given"); stopList.push_back("gives"); stopList.push_back("giving"); stopList.push_back("go"); stopList.push_back("goes"); stopList.push_back("gone"); stopList.push_back("got"); stopList.push_back("gotten"); stopList.push_back("h"); stopList.push_back("had"); stopList.push_back("happens"); stopList.push_back("hardly"); stopList.push_back("has"); stopList.push_back("hasn"); stopList.push_back("have"); stopList.push_back("haven"); stopList.push_back("having"); stopList.push_back("he"); stopList.push_back("hed"); stopList.push_back("hence"); stopList.push_back("her"); stopList.push_back("here"); stopList.push_back("hereafter"); stopList.push_back("hereby"); stopList.push_back("herein"); stopList.push_back("heres"); stopList.push_back("hereupon"); stopList.push_back("hers"); stopList.push_back("herself"); stopList.push_back("hes"); stopList.push_back("hi"); stopList.push_back("hid"); stopList.push_back("him"); stopList.push_back("himself"); stopList.push_back("his"); stopList.push_back("hither"); stopList.push_back("home"); stopList.push_back("how"); stopList.push_back("howbeit"); stopList.push_back("however"); stopList.push_back("hundred"); stopList.push_back("i"); stopList.push_back("id"); stopList.push_back("ie"); stopList.push_back("if"); stopList.push_back("im"); stopList.push_back("immediate"); stopList.push_back("immediately"); stopList.push_back("importance"); stopList.push_back("important"); stopList.push_back("in"); stopList.push_back("inc"); stopList.push_back("indeed"); stopList.push_back("index"); stopList.push_back("information"); stopList.push_back("instead"); stopList.push_back("into"); stopList.push_back("invention"); stopList.push_back("inward"); stopList.push_back("is"); stopList.push_back("isn"); stopList.push_back("it"); stopList.push_back("itd"); stopList.push_back("it"); stopList.push_back("its"); stopList.push_back("itself"); stopList.push_back("j"); stopList.push_back("jr"); stopList.push_back("just"); stopList.push_back("k"); stopList.push_back("keep"); stopList.push_back("keeps"); stopList.push_back("kept"); stopList.push_back("kg"); stopList.push_back("km"); stopList.push_back("know"); stopList.push_back("known"); stopList.push_back("knows"); stopList.push_back("l"); stopList.push_back("largely"); stopList.push_back("last"); stopList.push_back("lately"); stopList.push_back("later"); stopList.push_back("latter"); stopList.push_back("latterly"); stopList.push_back("laude"); stopList.push_back("least"); stopList.push_back("less"); stopList.push_back("lest"); stopList.push_back("let"); stopList.push_back("lets"); stopList.push_back("like"); stopList.push_back("liked"); stopList.push_back("likely"); stopList.push_back("line"); stopList.push_back("little"); stopList.push_back("ll"); stopList.push_back("look"); stopList.push_back("looking"); stopList.push_back("looks"); stopList.push_back("ltd"); stopList.push_back("m"); stopList.push_back("made"); stopList.push_back("mainly"); stopList.push_back("make"); stopList.push_back("makes"); stopList.push_back("many"); stopList.push_back("may"); stopList.push_back("maybe"); stopList.push_back("me"); stopList.push_back("mean"); stopList.push_back("means"); stopList.push_back("meantime"); stopList.push_back("meanwhile"); stopList.push_back("merely"); stopList.push_back("met"); stopList.push_back("mg"); stopList.push_back("mic"); stopList.push_back("might"); stopList.push_back("million"); stopList.push_back("miss"); stopList.push_back("ml"); stopList.push_back("more"); stopList.push_back("moreover"); stopList.push_back("most"); stopList.push_back("mostly"); stopList.push_back("mr"); stopList.push_back("mrs"); stopList.push_back("much"); stopList.push_back("mug"); stopList.push_back("must"); stopList.push_back("my"); stopList.push_back("myself"); stopList.push_back("n"); stopList.push_back("na"); stopList.push_back("name"); stopList.push_back("namely"); stopList.push_back("nay"); stopList.push_back("nd"); stopList.push_back("near"); stopList.push_back("nearly"); stopList.push_back("necessarily"); stopList.push_back("necessary"); stopList.push_back("need"); stopList.push_back("needs"); stopList.push_back("neither"); stopList.push_back("never"); stopList.push_back("nevertheless"); stopList.push_back("new"); stopList.push_back("next"); stopList.push_back("nine"); stopList.push_back("ninety"); stopList.push_back("no"); stopList.push_back("nobody"); stopList.push_back("non"); stopList.push_back("none"); stopList.push_back("nonetheless"); stopList.push_back("noone"); stopList.push_back("nor"); stopList.push_back("normally"); stopList.push_back("nos"); stopList.push_back("not"); stopList.push_back("noted"); stopList.push_back("nothing"); stopList.push_back("now"); stopList.push_back("nowhere"); stopList.push_back("o"); stopList.push_back("obtain"); stopList.push_back("obtained"); stopList.push_back("obviously"); stopList.push_back("of"); stopList.push_back("off"); stopList.push_back("often"); stopList.push_back("oh"); stopList.push_back("ok"); stopList.push_back("okay"); stopList.push_back("old"); stopList.push_back("omitted"); stopList.push_back("on"); stopList.push_back("once"); stopList.push_back("one"); stopList.push_back("ones"); stopList.push_back("only"); stopList.push_back("onto"); stopList.push_back("or"); stopList.push_back("ord"); stopList.push_back("org"); stopList.push_back("other"); stopList.push_back("others"); stopList.push_back("otherwise"); stopList.push_back("ought"); stopList.push_back("our"); stopList.push_back("ours"); stopList.push_back("ourselves"); stopList.push_back("out"); stopList.push_back("outside"); stopList.push_back("over"); stopList.push_back("overall"); stopList.push_back("owing"); stopList.push_back("own"); stopList.push_back("p"); stopList.push_back("page"); stopList.push_back("pages"); stopList.push_back("part"); stopList.push_back("particular"); stopList.push_back("particularly"); stopList.push_back("past"); stopList.push_back("per"); stopList.push_back("perhaps"); stopList.push_back("ph"); stopList.push_back("placed"); stopList.push_back("please"); stopList.push_back("plus"); stopList.push_back("poorly"); stopList.push_back("possible"); stopList.push_back("possibly"); stopList.push_back("potentially"); stopList.push_back("pp"); stopList.push_back("predominantly"); stopList.push_back("present"); stopList.push_back("previously"); stopList.push_back("primarily"); stopList.push_back("probably"); stopList.push_back("promptly"); stopList.push_back("proud"); stopList.push_back("provides"); stopList.push_back("put"); stopList.push_back("q"); stopList.push_back("que"); stopList.push_back("quickly"); stopList.push_back("quite"); stopList.push_back("qv"); stopList.push_back("r"); stopList.push_back("ran"); stopList.push_back("rather"); stopList.push_back("rd"); stopList.push_back("re"); stopList.push_back("readily"); stopList.push_back("really"); stopList.push_back("recent"); stopList.push_back("recently"); stopList.push_back("ref"); stopList.push_back("refs"); stopList.push_back("regarding"); stopList.push_back("regardless"); stopList.push_back("regards"); stopList.push_back("related"); stopList.push_back("relatively"); stopList.push_back("research"); stopList.push_back("respectively"); stopList.push_back("resulted"); stopList.push_back("resulting"); stopList.push_back("results"); stopList.push_back("right"); stopList.push_back("run"); stopList.push_back("s"); stopList.push_back("said"); stopList.push_back("same"); stopList.push_back("saw"); stopList.push_back("sat"); stopList.push_back("say"); stopList.push_back("saying"); stopList.push_back("says"); stopList.push_back("sec"); stopList.push_back("section"); stopList.push_back("see"); stopList.push_back("seeing"); stopList.push_back("seem"); stopList.push_back("seemed"); stopList.push_back("seeming"); stopList.push_back("seems"); stopList.push_back("seen"); stopList.push_back("self"); stopList.push_back("selves"); stopList.push_back("sent"); stopList.push_back("seven"); stopList.push_back("several"); stopList.push_back("shall"); stopList.push_back("she"); stopList.push_back("shed"); stopList.push_back("shes"); stopList.push_back("should"); stopList.push_back("shouldn"); stopList.push_back("show"); stopList.push_back("showed"); stopList.push_back("shown"); stopList.push_back("showns"); stopList.push_back("shows"); stopList.push_back("significant"); stopList.push_back("significantly"); stopList.push_back("similar"); stopList.push_back("similarly"); stopList.push_back("since"); stopList.push_back("six"); stopList.push_back("slightly"); stopList.push_back("so"); stopList.push_back("some"); stopList.push_back("somebody"); stopList.push_back("somehow"); stopList.push_back("someone"); stopList.push_back("somethan"); stopList.push_back("something"); stopList.push_back("sometime"); stopList.push_back("sometimes"); stopList.push_back("somewhat"); stopList.push_back("somewhere"); stopList.push_back("soon"); stopList.push_back("sorry"); stopList.push_back("specifically"); stopList.push_back("specified"); stopList.push_back("specify"); stopList.push_back("specifying"); stopList.push_back("still"); stopList.push_back("stop"); stopList.push_back("strongly"); stopList.push_back("sub"); stopList.push_back("substantially"); stopList.push_back("successfully"); stopList.push_back("such"); stopList.push_back("sufficiently"); stopList.push_back("suggest"); stopList.push_back("sup"); stopList.push_back("sure"); stopList.push_back("t"); stopList.push_back("take"); stopList.push_back("taken"); stopList.push_back("taking"); stopList.push_back("tell"); stopList.push_back("tends"); stopList.push_back("th"); stopList.push_back("than"); stopList.push_back("thank"); stopList.push_back("thanks"); stopList.push_back("thanx"); stopList.push_back("that"); stopList.push_back("thats"); stopList.push_back("the"); stopList.push_back("their"); stopList.push_back("theirs"); stopList.push_back("them"); stopList.push_back("themselves"); stopList.push_back("then"); stopList.push_back("thence"); stopList.push_back("there"); stopList.push_back("thereafter"); stopList.push_back("thereby"); stopList.push_back("thered"); stopList.push_back("therefore"); stopList.push_back("therein"); stopList.push_back("thereof"); stopList.push_back("therere"); stopList.push_back("theres"); stopList.push_back("thereto"); stopList.push_back("thereupon"); stopList.push_back("these"); stopList.push_back("they"); stopList.push_back("theyd"); stopList.push_back("theyre"); stopList.push_back("think"); stopList.push_back("this"); stopList.push_back("those"); stopList.push_back("thou"); stopList.push_back("though"); stopList.push_back("thoughh"); stopList.push_back("thousand"); stopList.push_back("throug"); stopList.push_back("through"); stopList.push_back("throughout"); stopList.push_back("thru"); stopList.push_back("thus"); stopList.push_back("til"); stopList.push_back("tip"); stopList.push_back("to"); stopList.push_back("together"); stopList.push_back("too"); stopList.push_back("took"); stopList.push_back("toward"); stopList.push_back("towards"); stopList.push_back("tried"); stopList.push_back("tries"); stopList.push_back("truly"); stopList.push_back("try"); stopList.push_back("trying"); stopList.push_back("ts"); stopList.push_back("twice"); stopList.push_back("two"); stopList.push_back("u"); stopList.push_back("un"); stopList.push_back("under"); stopList.push_back("unfortunately"); stopList.push_back("unless"); stopList.push_back("unlike"); stopList.push_back("unlikely"); stopList.push_back("until"); stopList.push_back("unto"); stopList.push_back("up"); stopList.push_back("upon"); stopList.push_back("ups"); stopList.push_back("us"); stopList.push_back("use"); stopList.push_back("used"); stopList.push_back("useful"); stopList.push_back("usefully"); stopList.push_back("usefulness"); stopList.push_back("uses"); stopList.push_back("using"); stopList.push_back("usually"); stopList.push_back("v"); stopList.push_back("value"); stopList.push_back("various"); stopList.push_back("ve"); stopList.push_back("very"); stopList.push_back("via"); stopList.push_back("viz"); stopList.push_back("vol"); stopList.push_back("vols"); stopList.push_back("vs"); stopList.push_back("w"); stopList.push_back("want"); stopList.push_back("wants"); stopList.push_back("was"); stopList.push_back("wasnt"); stopList.push_back("wasnt"); stopList.push_back("way"); stopList.push_back("we"); stopList.push_back("wed"); stopList.push_back("welcome"); stopList.push_back("went"); stopList.push_back("were"); stopList.push_back("werent"); stopList.push_back("what"); stopList.push_back("whatever"); stopList.push_back("whats"); stopList.push_back("when"); stopList.push_back("whence"); stopList.push_back("whenever"); stopList.push_back("where"); stopList.push_back("whereafter"); stopList.push_back("whereas"); stopList.push_back("whereby"); stopList.push_back("wherein"); stopList.push_back("wheres"); stopList.push_back("whereupon"); stopList.push_back("wherever"); stopList.push_back("whether"); stopList.push_back("which"); stopList.push_back("while"); stopList.push_back("whim"); stopList.push_back("whither"); stopList.push_back("who"); stopList.push_back("whod"); stopList.push_back("whoever"); stopList.push_back("whole"); stopList.push_back("whom"); stopList.push_back("whomever"); stopList.push_back("whos"); stopList.push_back("whose"); stopList.push_back("why"); stopList.push_back("widely"); stopList.push_back("will"); stopList.push_back("willing"); stopList.push_back("wish"); stopList.push_back("with"); stopList.push_back("within"); stopList.push_back("without"); stopList.push_back("wont"); stopList.push_back("words"); stopList.push_back("world"); stopList.push_back("would"); stopList.push_back("wouldnt"); stopList.push_back("www"); stopList.push_back("x"); stopList.push_back("y"); stopList.push_back("yes"); stopList.push_back("yet"); stopList.push_back("you"); stopList.push_back("youd"); stopList.push_back("your"); stopList.push_back("youre"); stopList.push_back("yours"); stopList.push_back("yourself"); stopList.push_back("yourselves"); stopList.push_back("z"); stopList.push_back("zero"); } }
CMakeLists.txt¶
cmake_minimum_required(VERSION 3.3 FATAL_ERROR) project(WordCloud) find_package(VTK COMPONENTS vtkCommonColor vtkCommonCore vtkCommonDataModel vtkIOImage vtkImagingCore vtkImagingSources vtkInteractionImage vtkInteractionStyle vtkRenderingContextOpenGL2 vtkRenderingCore vtkRenderingFreeType vtkRenderingGL2PSOpenGL2 vtkRenderingOpenGL2 QUIET) if (NOT VTK_FOUND) message("Skipping WordCloud: ${VTK_NOT_FOUND_MESSAGE}") return () endif() message (STATUS "VTK_VERSION: ${VTK_VERSION}") if (VTK_VERSION VERSION_LESS "8.90.0") # old system include(${VTK_USE_FILE}) add_executable(WordCloud MACOSX_BUNDLE WordCloud.cxx ) target_link_libraries(WordCloud PRIVATE ${VTK_LIBRARIES}) else () # include all components add_executable(WordCloud MACOSX_BUNDLE WordCloud.cxx ) target_link_libraries(WordCloud PRIVATE ${VTK_LIBRARIES}) # vtk_module_autoinit is needed vtk_module_autoinit( TARGETS WordCloud MODULES ${VTK_LIBRARIES} ) endif ()
Download and Build WordCloud¶
Click here to download WordCloud and its CMakeLists.txt file. Once the tarball WordCloud.tar has been downloaded and extracted,
cd WordCloud/build
If VTK is installed:
cmake ..
If VTK is not installed but compiled on your system, you will need to specify the path to your VTK build:
cmake -DVTK_DIR:PATH=/home/me/vtk_build ..
Build the project:
make
and run it:
./WordCloud
WINDOWS USERS
Be sure to add the VTK bin directory to your path. This will resolve the VTK dll's at run time.