Constructing QImage from unsigned char* data - qt

I encountered a problem with passing Image object (captured with Point Grej FlyCapture2 SDK) to QImage object. I am getting a pointer associated with Image data by function:
virtual unsigned char* FlyCapture2::GetData ( )
and then loading the data by:
QImage::QImage ( uchar * data, int width, int height, int bytesPerLine, Format format )
Formats of data of both Image objects are 8-bit monocolor. BytesPerLine parameter should be equal to width of the Image (I've already checked it by saving FlyCapture2::Image to .bmp and then loading it to QImage).
Do you thing the problem is casting from unsigned char* to uchar*?
Do you have any other ideas? Copying image pixel by pixel is much too slow.
EDIT: I am converting Image captured by FlyCapture into the FlyCapture2::PIXEL_FORMAT_RGB8 , for which: R = G = B = 8 bits, within PGR::SnapShot() function. SnapShot() returns unsigned char* const.
and here is a part of my Qt display function:
unsigned char *const img = PGRSystem->SnapShot();
QImage Img(img, 1024, 768, QImage::Format_RGB888);
QGraphicsScene *Scene = new QGraphicsScene();
Scene->addPixmap(QPixmap::fromImage(Img));
ui.ImageView->setScene(Scene);
ui.ImageView->fitInView(ui.ImageView->itemAt(100,100));
delete [] Scene;
I also tried to save Img to file, but got unhandled exception then. I tried other pixel format pairs (FlyCapture2::PIXEL_FORMAT_RGB - 24 bit RGB with QImage::RGB888 and FlyCapture2::PIXEL_FORMAT_RGBU32 with QImage::RGB32)
It is also worth to mention that QImage constuctor, which I am using, does not set the colorTable (I am getting exception when checking if QImage is in grayScale).
I need a little more help I guess.

First thing - QImage doesn't support a native greyscale image, which is what it sounds as if you're getting as output - so I would be curious what Format argument you're using. Probably the easiest solution, though memory-inefficent, will be to expand your greyscale image to RGB by copying each value three times (into a new QByteArray).
An additional concern is that the particular QImage constructor you're using, does not copy the underlying data, so you need be sure the pointer returned from GetData() outlives the QImage - or force the QImage to make a copy internally, using, say, QImage::copy.
Seeing more code would help, as other respondents noted above.

Thanks a lot for your help, you were right about the Image formats. Unfortunatelly the main problem was associated with passing the pointer between functions. In PGR::SnapShot() I was creating FlyCapture2::Image and then I was getting the pointer to data. FlyCapture2::Image was detructed when exit the function so returned pointer was BadPtr.

Related

Qt Set image to label reference variable

I have some pictures in the resource file and their file names correspond to their staffIds. this is how I set the picture into my QLabel but nothing is shown.
QString staffId;
staffId=ui->lineEdit_staffID->text();
QPixmap managerPic(":/staff/\'"+staffId+"\'.jpg");
managerInterface.ui->label_mpic->setScaledContents(true);
managerInterface.ui->label_mpic->setPixmap(managerPic);
I'm with #Mike here, most probably the single quotes aren't part of your filenames. You can use the debugger to see what is passed to the QPixmap constructor, or put the name into a separate QString variable and write it to qDebug() to see what it contains.
In general you better use QString::arg() to build strings instead of concatenation; usually it's easier to read and understand:
QPixmap managerPic(QString(":/staff/\'%1\'.jpg").arg(staffId));
QPixmap managerPic(QString(":/staff/%1.jpg").arg(staffId));

Qt-GUI Testing with Squish or other stuff

Is there a way to find out the filename of a QPixmap? My intention was to test which pixmap is currently set.
I've tried Squish to find out any properties, but I've get only access to some stuff like width, height etc
I assume that while you writing a test you already know which image you want to see. You can convert QPixmap to QImage and check if it contains the same image as expected:
bool same = QImage(filename) == pixmap.toImage();
It's not efficient but should be ok for testing purposes.

cudaMemcpy affects other variables

Here's my code for a program that does a histogram on an image then a prefix sum scan on the histogram http://codepad.org/4RMtWn1e. The problem is at line 396, which correctly outputs the value of numBins (number of bins for histogram) at 1024. I than copy the histogram from device memory back to host memory. This somehow changes the value of numBins and the next output of that is 0. That seems very strange. I didn't make any specific modifications to numBins, but it changes the value anyway. I feel like if I can figure this out, It will me understand why my program isn't working.
This is wrong:
unsigned int* h_histogram;
h_histogram = (unsigned int*) malloc(sizeof(unsigned int)* 1024);
std::cout << numBins;
checkCudaErrors(cudaMemcpy(&h_histogram, d_histogram, sizeof(unsigned int)* numBins, cudaMemcpyDeviceToHost));
^
|
h_histogram is already a pointer
Instead do this:
checkCudaErrors(cudaMemcpy(h_histogram, d_histogram, sizeof(unsigned int)* numBins, cudaMemcpyDeviceToHost));
(the only change being to remove the ampersand in front of h_histogram
I'm not sure really why numBins got corrupted exactly, but this particular errant cudaMemcpy operation would not be copying to the destination you expect, instead it would overwrite the pointer value stored at h_histogram as well as anything that came after it. And if numBins happened to be stored after it, it would overwrite that also.

Qt QSharedMemory Segmentation Faults after Several Successful Writes

I'm using QSharedMemory to store some data and want to subsequently append data to what is contained there. So I call the following code several times with new data. The "audioBuffer" is new data given to this function. I can call this function about 4-7 times ( and it varies ) before it seg faults on the memcpy operation. The size of the QSharedMemory location is huge so in the few calls that I do before seg faulting, there is no issue of memcpy copying data beyond it's boundaries. Also, m_SharedAudioBuffer.errorString() gives no errors up to the memcpy operation. Currently, I only have one process using this QSharedMemory segment. I also tried to write continually without appending each time and that works fine, so something is happening when I try to append more data to the shared memory segment. Any ideas? Thanks!
// Get the buffer size for the current audio buffer in shared memory
int bufferAudioDataSizeBytes = readFromSharedAudioBufferSizeMemory(); // This in number of bytes
// Create a bytearray with our data currently in the shared buffer
char* bufferAudioData = readFromSharedAudioBufferMemory();
QByteArray currentAudioStream = QByteArray::fromRawData(bufferAudioData,bufferAudioDataSizeBytes);
QByteArray currentAudioStreamDeepCopy(currentAudioStream);
currentAudioStreamDeepCopy.append(audioBuffer);
dataSize = currentAudioStreamDeepCopy.size();
//#if DEBUG
qDebug() << "Inserting audio buffer, new size is: " << dataSize;
//#endif
writeToSharedAudioBufferSizeMemory( dataSize ); // Just the size of what we received
// Write into the shared memory
m_SharedAudioBuffer.lock();
// Clear the buffer and define the copy locations
memset(m_SharedAudioBuffer.data(), '\0', m_SharedAudioBuffer.size());
char *to = (char*)m_SharedAudioBuffer.data();
char *from = (char*)audioBuffer.data();
// Now perform the actual copy operation to store the buffer
memcpy( to, from, dataSize );
// Release the lock
m_SharedAudioBuffer.unlock();
EDIT: Perhaps, this is due to my target embedded device which is very small. The available RAM is large when I am trying to write to shared memory, but I notice that in the /tmp directory ( which is only given 4Mb ) I have the following entries - the size is not nearly consumed in /tmp though so I'm not sure why I couldn't allocate more memory, also the QSharedMemory::create method never fails for my maximum size of 960000:
# cd /tmp/
# ls
QtSettings
lib
qipc_sharedmemory_AudioBufferData2a7d5f1a29e3d27dac65b4f350d76a0dfd442222
qipc_sharedmemory_AudioBufferSizeData6b7acc119f94322a6794cbca37ed63df07b733ab
qipc_systemsem_AudioBufferData2a7d5f1a29e3d27dac65b4f350d76a0dfd442222
qipc_systemsem_AudioBufferSizeData6b7acc119f94322a6794cbca37ed63df07b733ab
qtembedded-0
run
The problem seemed to be that I was using QByteArray's ::fromRawData on the pointer returned by the shared memory segment. When I copied that data explicitly using memcpy on this pointer, and then constructed my QByteArray using the copied data, then the seg faults stopped.

QAudioInput::byteReady() and QIODevice::read() giving different number of bytes

I am having a doubt with the following code snippet…
const qint64 bytesReady = m_audioInput->bytesReady();
const qint64 bytesSpace = m_buffer.size() - m_dataLength;
const qint64 bytesToRead = qMin(bytesReady, bytesSpace);
const qint64 bytesRead = m_audioInputIODevice->read(m_buffer.data() + m_dataLength, bytesToRead);
bytesReady() method is giving me a particular number of bytes and am passing these number of bytes to the read() of QIODevice which will return me the number of bytes read.
The problem is that bytesRead is not equal to bytesToRead.
And am getting fixed number of bytes from read method i.e 320, 640, 960, 1280, etc. and this depends on byteToRead.
There is no direct relation between the QAudioInput::bytesReady() and the QIODevice on which it is writing its samples.
QAudioInput maintains internally a IO device (system dependent) to the audio system, which is analog to a read-only QIODevice.
When you call bytesReady, it returns the number of bytes available to be read, analog to QIODevice::bytesAvailable(). Those have not yet been written to the output QIODevice, so when you do the m_audioInputIODevice->read just after it, without processing events, you're actually getting the samples which have been written earlier, not the ones still in the audio buffer.
This, plus the buffering of the IODevice, explains why the numbers might be different, and I don't see a way to synchronize them together.
Actually, you should do:
const qint64 bytesRead = m_audioInputIODevice->read(m_buffer.data() + m_dataLength, bytesSpace);
to get whatever is available from the IODevice, up to your available buffer space.
Better yet:
Use ->readAll() which returns a QByteArray "qba"
...then use sz=qba.size() which will tell you what you GOT (may be zero)
...then do something with it using sz and qba.data();
...seems to be without bugs unlike much of QAudioInput, which is incredibly broken, for instance, arbitrary sample rate limit of 48000 under Windows but not OSX, pull mode uses foreground thread so will break up constantly in any real situation, bytesReady() is meaningless... Worst. Qt. Routine. Evar!

Resources