I want to create Axial, Sagittal and Coronal views from a volume. At first I say that my volume is achieved from a series of DICOM images using DicomSeriesReadImageWrite2.cxx from itk library. The output is a .mha file.
Now I want to create different views using this data. So I used image ImageSlicing.cxx example. But the out put is a black window.
What shoud I do?
This is the code:
#include <vtkSmartPointer.h>
#include <vtkImageReader2.h>
#include <vtkImageData.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include "vtkSmartPointer.h"
#include "vtkImageReader2.h"
#include "vtkMatrix4x4.h"
#include "vtkImageReslice.h"
#include "vtkLookupTable.h"
#include "vtkImageMapToColors.h"
#include "vtkImageActor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkCommand.h"
#include "vtkImageData.h"
#include "vtkImageMapper3D.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkInformation.h"
#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
// The mouse motion callback, to turn "Slicing" on and off
class vtkImageInteractionCallback : public vtkCommand
{
public:
static vtkImageInteractionCallback *New() {
return new vtkImageInteractionCallback;
};
vtkImageInteractionCallback() {
this->Slicing = 0;
this->ImageReslice = nullptr;
this->Interactor = nullptr;
};
void SetImageReslice(vtkImageReslice *reslice) {
this->ImageReslice = reslice;
};
vtkImageReslice *GetImageReslice() {
return this->ImageReslice;
};
void SetInteractor(vtkRenderWindowInteractor *interactor) {
this->Interactor = interactor;
};
vtkRenderWindowInteractor *GetInteractor() {
return this->Interactor;
};
void Execute(vtkObject *, unsigned long event, void *) override
{
vtkRenderWindowInteractor *interactor = this->GetInteractor();
int lastPos[2];
interactor->GetLastEventPosition(lastPos);
int currPos[2];
interactor->GetEventPosition(currPos);
if (event == vtkCommand::LeftButtonPressEvent)
{
this->Slicing = 1;
}
else if (event == vtkCommand::LeftButtonReleaseEvent)
{
this->Slicing = 0;
}
else if (event == vtkCommand::MouseMoveEvent)
{
if (this->Slicing)
{
vtkImageReslice *reslice = this->ImageReslice;
// Increment slice position by deltaY of mouse
int deltaY = lastPos[1] - currPos[1];
reslice->Update();
double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
// move the center point that we are slicing through
double point[4];
double center[4];
point[0] = 0.0;
point[1] = 0.0;
point[2] = sliceSpacing * deltaY;
point[3] = 1.0;
matrix->MultiplyPoint(point, center);
matrix->SetElement(0, 3, center[0]);
matrix->SetElement(1, 3, center[1]);
matrix->SetElement(2, 3, center[2]);
interactor->Render();
}
else
{
vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
interactor->GetInteractorStyle());
if (style)
{
style->OnMouseMove();
}
}
}
};
private:
// Actions (slicing only, for now)
int Slicing;
// Pointer to vtkImageReslice
vtkImageReslice *ImageReslice;
// Pointer to the interactor
vtkRenderWindowInteractor *Interactor;
};
// The program entry point
int main(int argc, char *argv[])
{
//if (argc < 2)
//{
// cout << "Usage: " << argv[0] << " DATADIR/headsq/quarter" << endl;
// return 1;
//}
// Start by loading some data.
std::string inputFilename = "out.mha";
// Read file
vtkSmartPointer<vtkImageReader2> reader =
vtkSmartPointer<vtkImageReader2>::New();
reader->SetFileName(inputFilename.c_str());
reader->SetDataScalarTypeToUnsignedChar();
reader->Update();
// Calculate the center of the volume
int extent[6];
double spacing[3];
double origin[3];
reader->GetOutputInformation(0)->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), extent);
reader->GetOutput()->GetSpacing(spacing);
reader->GetOutput()->GetOrigin(origin);
double center[3];
center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);
// Matrices for axial, coronal, sagittal, oblique view orientations
//static double axialElements[16] = {
// 1, 0, 0, 0,
// 0, 1, 0, 0,
// 0, 0, 1, 0,
// 0, 0, 0, 1 };
//static double coronalElements[16] = {
// 1, 0, 0, 0,
// 0, 0, 1, 0,
// 0,-1, 0, 0,
// 0, 0, 0, 1 };
static double sagittalElements[16] = {
0, 0,-1, 0,
1, 0, 0, 0,
0,-1, 0, 0,
0, 0, 0, 1 };
//static double obliqueElements[16] = {
// 1, 0, 0, 0,
// 0, 0.866025, -0.5, 0,
// 0, 0.5, 0.866025, 0,
// 0, 0, 0, 1 };
// Set the slice orientation
vtkSmartPointer<vtkMatrix4x4> resliceAxes =
vtkSmartPointer<vtkMatrix4x4>::New();
resliceAxes->DeepCopy(sagittalElements);
// Set the point through which to slice
resliceAxes->SetElement(0, 3, center[0]);
resliceAxes->SetElement(1, 3, center[1]);
resliceAxes->SetElement(2, 3, center[2]);
// Extract a slice in the desired orientation
vtkSmartPointer<vtkImageReslice> reslice =
vtkSmartPointer<vtkImageReslice>::New();
reslice->SetInputConnection(reader->GetOutputPort());
reslice->SetOutputDimensionality(2);
reslice->SetResliceAxes(resliceAxes);
reslice->SetInterpolationModeToLinear();
// Create a greyscale lookup table
vtkSmartPointer<vtkLookupTable> table =
vtkSmartPointer<vtkLookupTable>::New();
table->SetRange(0, 2000); // image intensity range
table->SetValueRange(0.0, 1.0); // from black to white
table->SetSaturationRange(0.0, 0.0); // no color saturation
table->SetRampToLinear();
table->Build();
// Map the image through the lookup table
vtkSmartPointer<vtkImageMapToColors> color =
vtkSmartPointer<vtkImageMapToColors>::New();
color->SetLookupTable(table);
color->SetInputConnection(reslice->GetOutputPort());
// Display the image
vtkSmartPointer<vtkImageActor> actor =
vtkSmartPointer<vtkImageActor>::New();
actor->GetMapper()->SetInputConnection(color->GetOutputPort());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(actor);
vtkSmartPointer<vtkRenderWindow> window =
vtkSmartPointer<vtkRenderWindow>::New();
window->AddRenderer(renderer);
// Set up the interaction
vtkSmartPointer<vtkInteractorStyleImage> imageStyle =
vtkSmartPointer<vtkInteractorStyleImage>::New();
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetInteractorStyle(imageStyle);
window->SetInteractor(interactor);
window->Render();
vtkSmartPointer<vtkImageInteractionCallback> callback =
vtkSmartPointer<vtkImageInteractionCallback>::New();
callback->SetImageReslice(reslice);
callback->SetInteractor(interactor);
imageStyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imageStyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);
// Start interaction
// The Start() method doesn't return until the window is closed by the user
interactor->Start();
return EXIT_SUCCESS;
}
and this is the output:
The problem was in reading data. I used pointer to read my data and problem solved.
Related
I have read a material below and tested some code.
Does IOCP creates its own threads?
My codes are as below:
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
using namespace std;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
cout << mO->number << endl;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// TODO: sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}
I thought, if numberOfConcurrentThreads works, only a thread that cout '1' should be running, not all five threads.
However, result is as below.
All overlapped works were being processed by worker threads..
Why all overlapped works were processed by 5 worker threads?
I think it should be 1 worker thread that works because numberOfConcurrentThreads is 1.
I hope your wise answers.
Thank you for reading.
I figured it out.
It is because I called 'cout' in my worker thread's function.
I think 'cout' invokes IO interrupt for my worker thread, and it makes IOCP signal another worker thread.
My test code is as below.
You can run this code, and press any key except 'e'.('e' is for exit.)
You can see which worker thread works in IOCP.
#include <functional>
#include <stdio.h>
#include <iostream>
#include <crtdbg.h>
#include <conio.h>
#include <array>
#include <unordered_map>
int iocp_test = -1;
namespace IOCP_test {
struct myOverlapped {
OVERLAPPED overLapped;
int number;
};
DWORD WINAPI myCallBack(LPVOID completionPort) {
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
while (true) {
auto success = GetQueuedCompletionStatus(
(HANDLE)completionPort,
&NumberOfByteTransfered,
(LPDWORD)&CompletionKey,
&overlappedPointer,
INFINITE);
if (success) {
myOverlapped* mO = (myOverlapped*)overlappedPointer;
while (true) {
iocp_test = mO->number;
}
//Sleep(10);
//PostQueuedCompletionStatus(completionPort, 0, 0, overlappedPointer);
}
}
}
void IOCP_test() {
// sleep을 안걸었는데.. 왜 5개 스레드가 모두 작동할까?
// cout 같은 IO 인터럽트가 워커 스레드에서 호출되면 IOCP에서 그 스레드는 작업 중이 아닌 스레드로 판단하는 것 같다.
int workerThreadCount = 5;
HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 2);
vector<HANDLE> workerThreadVector;
DWORD NumberOfByteTransfered = 0;
VOID* CompletionKey = NULL;
OVERLAPPED* overlappedPointer = NULL;
for (DWORD i = 0; i < workerThreadCount; i++)
{
HANDLE WorkerThread = CreateThread(NULL, 0, myCallBack, hIOCP, 0, NULL);
workerThreadVector.push_back(WorkerThread);
}
myOverlapped a1;
a1.number = 1;
myOverlapped a2;
a2.number = 2;
myOverlapped a3;
a3.number = 3;
myOverlapped a4;
a4.number = 4;
myOverlapped a5;
a5.number = 5;
if (hIOCP) {
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a1);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a2);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a3);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a4);
PostQueuedCompletionStatus(hIOCP, 0, 0, (LPOVERLAPPED)&a5);
}
char key;
while (true) {
key = _getch();
cout << iocp_test;
if (key == 'e') {
break;
}
if (key == 'n') {
cout << endl;
}
}
for (DWORD i = 0; i < workerThreadVector.size(); i++)
{
CloseHandle(workerThreadVector[i]);
}
if (hIOCP) {
CloseHandle(hIOCP);
}
}
//IOCP_test::IOCP_test();
}
int main()
{
IOCP_test::IOCP_test();
_CrtDumpMemoryLeaks();
return 0;
}
I'm writing an application in Linux using Xlib to manage a window and cairo to draw some text in it. The text content of the window changes during the execution, so I want to adapt the window size to match that of the text extent. If the size of the text extent does not change, the window is always correctly updated with the new text.
But when the text extent changes, and so the window is resized accordingly, the window is cleared but the new text is never shown. Only if there is no call to XResizeWindow the text is actually displayed. The code I'm using is
if (/* Text extent is changed */)
{
XResizeWindow (display, window, new_width, new_height);
cairo_xlib_surface_set_size (surface, new_width, new_height);
}
XClearWindow (display, window);
/* ... Cairo code to draw the text ... */
// cairo_surface_flush (surface);
// XFlush (display);
I have also tried to add after the Cairo code that draws the text the methods cairo_surface_flush and XFlush (commented in the example) but nothing changes.
EDIT: I solved the problem using two threads: the first thread with the usual loop for listening to the Expose events plus the code to redraw the content and the second thread that issues the resize of the window and sends an Expose event to wake up the first thread.
In this example the window is resized every 500 ms to random width and height and a progressive counter is displayed in it at every resize. I use C++11, compile with:
g++ -std=c++11 -o test test.cpp -lX11 -lcairo -lpthread
The code is:
#include <random>
#include <chrono>
#include <thread>
#include <string>
#include <X11/Xlib.h>
#include <cairo/cairo-xlib.h>
Display * d;
Window w;
cairo_surface_t * surface;
int width = 300, height = 300;
unsigned char counter = 0;
std::random_device rd;
std::knuth_b gen (rd ());
std::uniform_int_distribution < > dist (150, 300);
void logic ()
{
XEvent send_event;
send_event.type = Expose;
send_event.xexpose.window = w;
while (true)
{
std::this_thread::sleep_for (std::chrono::milliseconds (500));
++ counter;
width = dist (gen);
height = dist (gen);
cairo_xlib_surface_set_size (surface, width, height);
XResizeWindow (d, w, width, height);
XSendEvent (d, w, False, ExposureMask, & send_event);
XFlush (d);
}
}
int main ( )
{
XInitThreads ();
d = XOpenDisplay (NULL);
w = XCreateSimpleWindow (d, RootWindow (d, 0), 0, 0, width, height, 0, 0, 0x000000);
XMapWindow (d, w);
XSelectInput (d, w, ExposureMask | KeyPressMask);
surface = cairo_xlib_surface_create (d, w, DefaultVisual (d, 0), width, height);
cairo_t * cairo = cairo_create (surface);
cairo_select_font_face (cairo, "FreeSans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cairo, 40 );
cairo_set_source_rgb (cairo, 0.8, 0.8, 0.8);
cairo_move_to (cairo, 40.0, 60.0);
cairo_show_text (cairo, std::to_string (counter).c_str ());
XFlush (d);
std::thread T (logic);
XEvent event;
while (true)
{
XNextEvent (d, & event);
if (event.type == Expose)
{
XClearWindow (d, w);
cairo_move_to (cairo, 40.0, 60.0);
cairo_show_text (cairo, std::to_string (counter).c_str ());
}
else if (event.type == KeyPress)
{
XCloseDisplay (d);
return 0;
}
}
}
But a question remains: is it possible to obtain the same result using only one thread?
Here is a single-threaded version of your code. It is not nice, but it seems to work. The hard part is waiting for events from the X11 server and the timeout simultaneously. I do this with select() in the following code.
Note that I also handle ConfigureNotify events instead of assuming that XResizeWindow always does just what we want.
#include <random>
#include <chrono>
#include <thread>
#include <string>
#include <X11/Xlib.h>
#include <cairo/cairo-xlib.h>
#include <sys/time.h>
Display * d;
Window w;
cairo_surface_t * surface;
int width = 300, height = 300;
unsigned char counter = 0;
std::random_device rd;
std::knuth_b gen (rd ());
std::uniform_int_distribution < > dist (150, 300);
void do_update ()
{
++ counter;
width = dist (gen);
height = dist (gen);
XResizeWindow (d, w, width, height);
// Force a redraw
XClearArea(d, w, 0, 0, 0, 0, True);
}
int main ( )
{
XInitThreads ();
d = XOpenDisplay (NULL);
w = XCreateSimpleWindow (d, RootWindow (d, 0), 0, 0, width, height, 0, 0, 0x000000);
XMapWindow (d, w);
XSelectInput (d, w, ExposureMask | KeyPressMask);
surface = cairo_xlib_surface_create (d, w, DefaultVisual (d, 0), width, height);
cairo_t * cairo = cairo_create (surface);
cairo_select_font_face (cairo, "FreeSans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
cairo_set_font_size (cairo, 40 );
cairo_set_source_rgb (cairo, 0.8, 0.8, 0.8);
cairo_move_to (cairo, 40.0, 60.0);
cairo_show_text (cairo, std::to_string (counter).c_str ());
XFlush (d);
struct timeval next_update;
struct timeval now;
struct timeval interval = { 0, 500000 };
gettimeofday(&now, NULL);
timeradd(&now, &interval, &next_update);
while (true)
{
XEvent event;
gettimeofday(&now, NULL);
if (timercmp(&now, &next_update, >)) {
// Store time of next update
timeradd(&now, &interval, &next_update);
puts("update");
do_update();
}
if (!XPending(d)) {
struct timeval remaining;
fd_set fds;
int fd = ConnectionNumber(d);
FD_ZERO(&fds);
FD_SET(fd, &fds);
timersub(&next_update, &now, &remaining);
select(fd + 1, &fds, NULL, NULL, &remaining);
} else {
XNextEvent (d, & event);
if (event.type == Expose)
{
XClearWindow (d, w);
cairo_move_to (cairo, 40.0, 60.0);
cairo_show_text (cairo, std::to_string (counter).c_str ());
}
if (event.type == ConfigureNotify)
{
cairo_xlib_surface_set_size (surface, event.xconfigure.width, event.xconfigure.height);
}
else if (event.type == KeyPress)
{
XCloseDisplay (d);
return 0;
}
}
}
}
I have wrote a shape detection code with c++.
I am using Visual Studio 2013 Express Desktop Edition.
When I run the program it will give following error.
First-chance exception at 0x54EE3C77 (opencv_imgproc244d.dll) in Final.exe: 0xC0000005: Access violation reading location 0x05958000.
If there is a handler for this exception, the program may be safely continued.
Following is the code sample.
#include "stdafx.h"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <cv.h>
#include <highgui.h>
#include <windows.h>
void shapeDetectionNew(IplImage* img)
{
try
{
//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1);
cvCvtColor(img, imgGrayScale, CV_BGR2GRAY);
//thresholding the grayscale image to get better results
cvThreshold(imgGrayScale, imgGrayScale, 128, 255, CV_THRESH_BINARY);
CvSeq* contour; //hold the pointer to a contour
CvSeq* result; //hold sequence of points of a contour
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));
//***********************************
cv::Mat img = cv::imread("F:\\My Works\\Opencv\\Shape_Detection_Images\\shape.jpg");
//convert IplImage to Mat
//cv::Mat img(iplImg);
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
// Use Canny instead of threshold to catch squares with gradient shading
cv::Mat bw;
cv::Canny(gray, bw, 0, 50, 5);
// Find contours
std::vector<std::vector<cv::Point> > contours;
cv::findContours(bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
std::vector<cv::Point> approx;
cv::Mat dst = img.clone();
//***********************************
for (int i = 0; i < contours.size(); i++)
{
// Approximate contour with accuracy proportional
// to the contour perimeter
cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true)*0.02, true);
// Skip small or non-convex objects
if (std::fabs(cv::contourArea(contours[i])) < 100 || !cv::isContourConvex(approx))
continue;
if (approx.size() == 3)
{
setLabel(dst, "TRI", contours[i]); // Triangles
}
else if (approx.size() >= 4 && approx.size() <= 6)
{
// Number of vertices of polygonal curve
int vtc = approx.size();
// Get the cosines of all corners
std::vector<double> cos;
for (int j = 2; j < vtc + 1; j++)
cos.push_back(angle(approx[j%vtc], approx[j - 2], approx[j - 1]));
// Sort ascending the cosine values
std::sort(cos.begin(), cos.end());
// Get the lowest and the highest cosine
double mincos = cos.front();
double maxcos = cos.back();
// Use the degrees obtained above and the number of vertices
// to determine the shape of the contour
if (vtc == 4 && mincos >= -0.1 && maxcos <= 0.3)
setLabel(dst, "RECT", contours[i]);
else if (vtc == 5 && mincos >= -0.34 && maxcos <= -0.27)
setLabel(dst, "PENTA", contours[i]);
else if (vtc == 6 && mincos >= -0.55 && maxcos <= -0.45)
setLabel(dst, "HEXA", contours[i]);
}
else
{
// Detect and label circles
double area = cv::contourArea(contours[i]);
cv::Rect r = cv::boundingRect(contours[i]);
int radius = r.width / 2;
if (std::abs(1 - ((double)r.width / r.height)) <= 0.2 &&
std::abs(1 - (area / (CV_PI * std::pow((double)radius, 2)))) <= 0.2)
setLabel(dst, "CIR", contours[i]);
}
}
cv::imshow("Shape_Detection", dst);
}
catch (int e)
{
throw e;
}
}
int main()
{
try
{
// Create CvCapture object to grab data from the webcam
CvCapture* pCapture;
// Start capturing data from the webcam
pCapture = cvCaptureFromCAM(1);
// Define the IplImage pointers we're going to use as globals
IplImage* pFrame;
IplImage* pProcessedFrame;
IplImage* tempFrame;
pFrame = cvQueryFrame(pCapture);
//Create the low threshold slider
// Format: Slider name, window name, reference to variable for slider, max value of slider, callback function
cvCreateTrackbar("Low Threshold", "Edge_Detection", &lowSliderPosition, maxLowThreshold, onLowThresholdSlide);
// Create the high threshold slider
cvCreateTrackbar("High Threshold", "Edge_Detection", &highSliderPosition, maxHighThreshold, onHighThresholdSlide);
// Create a greyscale image which is the size of our captured image
pProcessedFrame = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
// Create a frame to use as our temporary copy of the current frame but in grayscale mode
tempFrame = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
char keypress;
bool quit = false;
int counterCheck = 1;
while (quit == false)
{
// Make an image from the raw capture data
// Note: cvQueryFrame is a combination of cvGrabFrame and cvRetrieveFrame
pFrame = cvQueryFrame(pCapture);
// Draw the original frame in our window
cvShowImage("Live_Cam", pFrame);
shapeDetectionNew(pFrame);
} // End of while loop
cvDestroyAllWindows();
}
catch (Exception ex)
{
}
return 1;
}
You are not checking that the result of
pFrame = cvQueryFrame(pCapture);
is not null. If it is, eventuallu this will get passed to cvCvtColor() and hence the exception.
Completely separate problem:imshow() will not display anything without a subsequent call to waitKey()
I've been trying and reading lots of resources on the internet, trying to find a way to get an UTF-8 keyboard (composed) input from a X Display. But I could not make it work.
I have tried the example code from this link (exaple 11-4), but no success.
I also have written a simple example (below) to try to make it work. My simple test case is to print an "é", which happens by typing the acute and then the e.
What is wrong?
Thanks,
Here is my example:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
int screen_num, width, height;
unsigned long background, border;
Window win;
XEvent ev;
Display *dpy;
XIM im;
XIC ic;
char *failed_arg;
XIMStyles *styles;
XIMStyle xim_requested_style;
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
if (setlocale(LC_ALL, "") == NULL) {
return 9;
}
if (!XSupportsLocale()) {
return 10;
}
if (XSetLocaleModifiers("") == NULL) {
return 11;
}
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "unable to connect to display");
return 7;
}
/* these are macros that pull useful data out of the display object */
/* we use these bits of info enough to want them in their own variables */
screen_num = DefaultScreen(dpy);
background = BlackPixel(dpy, screen_num);
border = WhitePixel(dpy, screen_num);
width = 400; /* start with a small window */
height = 200;
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */
0,0, /* x, y: the window manager will place the window elsewhere */
width, height, /* width, height */
2, border, /* border width & colour, unless you have a window manager */
background); /* background colour */
/* tell the display server what kind of events we would like to see */
XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask|KeymapStateMask);
/* okay, put the window on the screen, please */
XMapWindow(dpy, win);
im = XOpenIM(dpy, NULL, NULL, NULL);
if (im == NULL) {
fputs("Could not open input method\n", stdout);
return 2;
}
failed_arg = XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
if (failed_arg != NULL) {
fputs("XIM Can't get styles\n", stdout);
return 3;
}
int i;
for (i = 0; i < styles->count_styles; i++) {
printf("style %d\n", styles->supported_styles[i]);
}
ic = XCreateIC(im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL);
if (ic == NULL) {
printf("Could not open IC\n");
return 4;
}
XSetICFocus(ic);
/* as each event that we asked about occurs, we respond. In this
* case we note if the window's shape changed, and exit if a button
* is pressed inside the window */
while(1) {
XNextEvent(dpy, &ev);
switch(ev.type){
case KeymapNotify:
XRefreshKeyboardMapping(&ev.xmapping);
break;
case KeyPress:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
printf("count: %d\n", count);
if (status==XBufferOverflow)
printf("BufferOverflow\n");
if (count)
printf("buffer: %s\n", buf);
if (status == XLookupKeySym || status == XLookupBoth) {
printf("status: %d\n", status);
}
printf("pressed KEY: %d\n", keysym);
}
break;
case KeyRelease:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = XLookupString((XKeyEvent*)&ev, buf, 20, &keysym, NULL);
if (count)
printf("in release buffer: %s\n", buf);
printf("released KEY: %d\n", keysym);
}
break;
case ConfigureNotify:
if (width != ev.xconfigure.width
|| height != ev.xconfigure.height) {
width = ev.xconfigure.width;
height = ev.xconfigure.height;
printf("Size changed to: %d by %d", width, height);
}
break;
case ButtonPress:
XCloseDisplay(dpy);
return 0;
}
fflush(stdout);
}
}
You have to do this:
if (XFilterEvent(&ev, win))
continue;
in your event loop. This runs the input method machinery, without it you will get raw X events. For example, when you press a dead accent key followed by a letter key, and do not call XFilterEvent, you will get two KeyPress events as usual. But if you do the call, you will get three events. There are two raw events, for which XFilterEvent(&ev, win) returns True. And then there is one event synthesized by the input method, for which XFilterEvent(&ev, win) returns False. It is this third event that contains the accented character.
If you want both raw events and those synthesized by the input method, you can of course do your own raw event processing instead of continue.
Note you will need buf[count] = 0; in order to print buf correctly (or explicitly use a length), Xutf8LookupString doesn't null-terminate its output.
Finally, as mentioned in the comments, with recent versions of X11 you will need to specify a modify to XSetLocaleModifiers such as XSetLocaleModifiers("#im=none"), otherwise the extra events won't be generated.
Here is a corrected version of the code:
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>
#include <X11/Xlocale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char ** argv)
{
int screen_num, width, height;
unsigned long background, border;
Window win;
XEvent ev;
Display *dpy;
XIM im;
XIC ic;
char *failed_arg;
XIMStyles *styles;
XIMStyle xim_requested_style;
/* First connect to the display server, as specified in the DISPLAY
environment variable. */
if (setlocale(LC_ALL, "") == NULL) {
return 9;
}
if (!XSupportsLocale()) {
return 10;
}
if (XSetLocaleModifiers("#im=none") == NULL) {
return 11;
}
dpy = XOpenDisplay(NULL);
if (!dpy) {
fprintf(stderr, "unable to connect to display");
return 7;
}
/* these are macros that pull useful data out of the display object */
/* we use these bits of info enough to want them in their own variables */
screen_num = DefaultScreen(dpy);
background = BlackPixel(dpy, screen_num);
border = WhitePixel(dpy, screen_num);
width = 400; /* start with a small window */
height = 200;
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), /* display, parent */
0,0, /* x, y: the window manager will place the window elsewhere */
width, height, /* width, height */
2, border, /* border width & colour, unless you have a window manager */
background); /* background colour */
/* tell the display server what kind of events we would like to see */
XSelectInput(dpy, win, ButtonPressMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask);
/* okay, put the window on the screen, please */
XMapWindow(dpy, win);
im = XOpenIM(dpy, NULL, NULL, NULL);
if (im == NULL) {
fputs("Could not open input method\n", stdout);
return 2;
}
failed_arg = XGetIMValues(im, XNQueryInputStyle, &styles, NULL);
if (failed_arg != NULL) {
fputs("XIM Can't get styles\n", stdout);
return 3;
}
int i;
for (i = 0; i < styles->count_styles; i++) {
printf("style %d\n", (int)styles->supported_styles[i]);
}
ic = XCreateIC(im, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL);
if (ic == NULL) {
printf("Could not open IC\n");
return 4;
}
XSetICFocus(ic);
/* as each event that we asked about occurs, we respond. In this
* case we note if the window's shape changed, and exit if a button
* is pressed inside the window */
while(1) {
XNextEvent(dpy, &ev);
if (XFilterEvent(&ev, win))
continue;
switch(ev.type){
case MappingNotify:
XRefreshKeyboardMapping(&ev.xmapping);
break;
case KeyPress:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = Xutf8LookupString(ic, (XKeyPressedEvent*)&ev, buf, 20, &keysym, &status);
printf("count: %d\n", count);
if (status==XBufferOverflow)
printf("BufferOverflow\n");
if (count)
printf("buffer: %.*s\n", count, buf);
if (status == XLookupKeySym || status == XLookupBoth) {
printf("status: %d\n", status);
}
printf("pressed KEY: %d\n", (int)keysym);
}
break;
case KeyRelease:
{
int count = 0;
KeySym keysym = 0;
char buf[20];
Status status = 0;
count = XLookupString((XKeyEvent*)&ev, buf, 20, &keysym, NULL);
if (count)
printf("in release buffer: %.*s\n", count, buf);
printf("released KEY: %d\n", (int)keysym);
}
break;
case ConfigureNotify:
if (width != ev.xconfigure.width
|| height != ev.xconfigure.height) {
width = ev.xconfigure.width;
height = ev.xconfigure.height;
printf("Size changed to: %d by %d", width, height);
}
break;
case ButtonPress:
XCloseDisplay(dpy);
return 0;
}
fflush(stdout);
}
}
For Windows 7, what is the simplest way to render arbitrary shapes and text straight onto the desktop?
It must have the following properties:
1) Visible and always on top
3) Semi-transparent
2) Click through and type through, as if the objects are not there
Some notable examples range from the simple Fraps which renders framerate, to the complex Rainmeter which has tons of functionality.
EDIT0: I've looked at the Rainmeter sourcecode but I still have no idea how it renders objects...
EDIT1: Window Hud Behavior (Pass through clicks, can't be minimized) (Solutions such as this seem extremely restrictive, there must be a way to render stuff with as much freedom as Rainmeter?)
i am still working on it but here is part of it:
#include <algorithm>
#include <Windows.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <conio.h>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <stdio.h>
#include <cstdlib>
#include <string>
#include <memory>
#include <cstdio>
#include <glut.h>
#include <io.h>
#using <mscorlib.dll>
#using <System.dll>
using namespace System;
using namespace std;
#pragma comment(lib, "wininet.lib")
#pragma comment (lib, "Urlmon.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
HINSTANCE hInstance;
POINT Mouse;
HWND hwnd;
RECT rect;
HDC dc;
float Size = 100;
float angle = 0;
bool Dirty = false;
char TEX;
int posX = 0;
int posY = 0;
int storedDC;
void GetDesktopResolution(int& w, int& h){
RECT desktop;
const HWND hDesktop = GetDesktopWindow();
GetWindowRect(hDesktop, &desktop);
w = desktop.right;
h = desktop.bottom;
}
void EX(){
delete hInstance;
delete hwnd;
exit(0);
}
void Keys(){
if (GetAsyncKeyState(VK_ESCAPE)){
exit(0);
}
if (GetAsyncKeyState(VK_LBUTTON) && GetAsyncKeyState(VK_CONTROL)){
}
}
void Draw(){
int h;
int w;
//Declair Desktop Size
GetDesktopResolution(w, h);
angle += 0.1f;
if (angle >= 2 * 3.141592f){
angle -= 2 * 3.141592f;
}
GetCursorPos(&Mouse);
if (Dirty == true){
rect = { 0, 0, w, h };
RedrawWindow(hwnd, &rect, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW);
posX = Mouse.x;
posY = Mouse.y;
RedrawWindow(hwnd, &rect, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW);
Dirty = false;
}
dc = GetDC(hwnd);
storedDC = SaveDC(dc);
//DEFAULT_CHARSET - ANSI_CHARSET
HFONT FMain = CreateFont(36, 20, -300, 0, FW_DONTCARE, FALSE, TRUE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Times New Roman"));
SetTextColor(dc, RGB(255, 255, 255));
SetBkColor(dc, RGB(0, 255, 0));
SelectObject(dc, FMain);
TextOut(dc, 15, 15, L"This is what the program does!", 30);
RedrawWindow(hwnd, &rect, NULL, RDW_NOERASE | RDW_INVALIDATE | RDW_UPDATENOW);
RestoreDC(dc, storedDC);
ReleaseDC(hwnd, dc);
}
int main(int argc, char **argv){
int h;
int w;
//Declair Desktop Size
GetDesktopResolution(w, h);
// find Program Manager
hwnd = FindWindowEx(GetDesktopWindow(), 0, L"Progman", L"Program Manager");
// find SHELLDLL_DefView
hwnd = FindWindowEx(hwnd, 0, L"SHELLDLL_DefView", 0);
// find Desktop Folder
hwnd = FindWindowEx(hwnd, 0, L"SysListView32", L"FolderView");
if (hwnd == NULL){
MessageBox(NULL, L"Could not initiate window!", L"ERROR!", MB_OK);
EX();
}
while (1){
Keys();
Draw();
}
//Remove the drawing
rect = { Mouse.x - 50, Mouse.y - 50, Mouse.x + 50, Mouse.y + 50 };
InvalidateRect(hwnd, &rect, true);
delete hInstance;
delete hwnd;
return 0;
}