PDA

View Full Version : QImage::scaled cause "raster"/"grid"



wesley
28th January 2010, 06:31
Hello, every body ..
I am using Qt-4.6 to implement a camera application, that capture preview and the camera output on windows PC / linux PC,

I capture the camera raw RBG output from USB in a thread, then convert it to RGB888 format and store it in a QImage in another thread,
after that I use QPainter::drawImage to draw on a QWidget for previewing. if the camera resolution is not fit with the widget size, then the image would be scaled to the widget size i think.

As your see in the attached photos, the preview image seems fill with "grid", but if I directly save the QImage into a jpeg file, and watch it with a photo view tool, then it seems ok.


the camera output resolution is 864*600, and
1.jpg -- preview in a small widget,
2.jpg --- preview in a small widget, but large the previews one.
3.jpg --- the widget size is equal to the camera resolution.

How to fix this ?

or is there a better way to go ?

/WX

wysota
28th January 2010, 09:21
I think this effect is caused by interference of the thin lines (raster) in the background of this image. Try capturing something with a solid (white?) background and see if the problem persists.

wesley
28th January 2010, 15:16
I think this effect is caused by interference of the thin lines (raster) in the background of this image. Try capturing something with a solid (white?) background and see if the problem persists.

the paper you saw in the attached images is already a whilte A4 paper with some black texts.

/WX

wysota
28th January 2010, 20:10
But I can see a grid on every one of those three pictures. I don't think scaling QImage would cause this.

wesley
29th January 2010, 03:44
But I can see a grid on every one of those three pictures. I don't think scaling QImage would cause this.

Thanks for reply.

see the new attached photos come with this reply,

11.jpg -- the camera resolution is 2592*1944, I capture a frame and then QImage::save() to save it into 11.jpg, the image resolution is not scaled,
12.jpg -- the camera resolution is 2592*1944, use QImage::scaled() to scale the resolution to 400*300, then save it into 12.jpg

21.jpg -- the camera resolution is 864*600, I capture a frame and then QImage::save() save it into 21.jpg, the image resolution is not scaled,
22.jpg -- the camera resolution is 864*600, use QImage::scaled() to scale the resolution to 400*300, then save it into 22.jpg

as you see, the 12.jpg and 22.jpg is filled with "grid", but the 11.jpg and 21.jpg seems ok.


/WX

wysota
29th January 2010, 11:34
Could you post the exact code that reveals the problem?

wesley
1st February 2010, 08:13
Could you post the exact code that reveals the problem?



QString photoName = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");
photoName.append(".jpeg");
QImage photo(photoData, photoSize.width(), photoSize.height(), QImage::Format_RGB888);
photo = photo.scaled(800, 600); // with or without this line
photo.save(photoName);

wysota
1st February 2010, 10:20
What if you save the image not as jpeg but as png or bmp?

wesley
2nd February 2010, 09:53
It seems caused by QImage::scaled(), which used by QPainter::drawImage() internally,

I tried the way described in this url http://labs.qt.nokia.com/blogs/2009/01/26/creating-thumbnail-preview, the result image seems more better.

Am i right ?

/WX

wesley
16th April 2010, 09:27
I think this effect is caused by interference of the thin lines (raster) in the background of this image. Try capturing something with a solid (white?) background and see if the problem persists.


hi guy, have a look at the attached image, it is a screen shot, it seems that this problem is caused by QPainter::drawImage,

but i am not sure what is going on .

wesley
16th April 2010, 09:50
hello, guy

I am using Qt-4.6.2 to implement a camera application on win xp profession sp2,

I capture the camera stream, then construct a QImage, then draw it on a widget use QPainter,


painter->drawImage(targetRect, image);


if I adjust the widget size to fit the image size, it seems ok,
but if the wiget size is smaller than image size, there are some "grid/raster" on the widget.

Have a look at the attached photos,

the 1 image: it is a screen shot, the widget size fit the image size,
the 2 image: it is a screen shot, the widget size is smaller than the image size.

NOTE: it adjust some YUV properties of the image, to make the "grid/raster" more easier to see, i am sure that this problem isn't caused by my YUV adjust routines.

thanks.

/WX

wesley
19th April 2010, 03:50
Hello, guys, please have at look at below code that i used to scaled a image.

QImage image("0.bmp");
//image = image.scaled(QSize(442, 332), Qt::KeepAspectRatio, Qt::FastTransformation);
image = image.scaled(QSize(442, 332));
image.save("1.bmp");


There are some "raster"/"grid" at the bottom of the the result image "1.bmp".

see the attached images for more details.

0.bmp is grabbed from a camera running on "916x688" resolution, convert to QImage::Image_RGB888, and then save as "bmp" format.

Thanks

/WX

faldzip
19th April 2010, 08:13
what if you use SmoothTransformation? what if you scale your image to exactly 1/2, 1/4 of original resolution? what if you scale other image than captured with your camera?
can you attach the original image?

wesley
19th April 2010, 09:03
what if you use SmoothTransformation? what if you scale your image to exactly 1/2, 1/4 of original resolution? what if you scale other image than captured with your camera?
can you attach the original image?

1. the "SmoothTransformation" seems more better, but still has the "raster"

2. scale to 1/2 it is ok, i don't know why!

3. scale other image is ok!

4. the 0.jpg/0.bmp(no matter jpg or bmp format) is the original on the captured from my camera.

and I also tried "CImg", a open source image library, which has the ability to scale image, the problem still be there.

So, i think this problem is not caused by QImage::scale, but dued to my camera setup or the routine convert raw data to RGB888, below is the convert routine, please have a look , tell me if something wrong.


int Bayer_GRBG_To_RGB888(const uint8_t *src, uint8_t *dst, int width, int height)
{
assert(src != NULL);
assert(dst != NULL);

const uint8_t *pSrcRow = src;
uint8_t *pDstRow = dst;
const uint8_t *pSrcRowNext = 0;
const uint8_t *pSrcRowPrev = 0;
long nSrcBytesPerRow = 1 * width;
long nDstBytesPerRow = 3 * width;
long nSrcWidth = width;
long nSrcHeight = height;

for (long nRow=0; nRow < nSrcHeight; nRow++) {
pSrcRowNext = pSrcRow + nSrcBytesPerRow;
if (nRow == 0) pSrcRowPrev = pSrcRowNext;
else pSrcRowPrev = pSrcRow - nSrcBytesPerRow;

if (nRow == nSrcHeight-1) pSrcRowNext = pSrcRowPrev;

for (long nCol = 0, k = 0; nCol < nSrcWidth; nCol++,k += 3) {
long nColNext = nCol + 1;
long nColPrev = nCol - 1;
if (nCol == 0) nColPrev = nColNext;
if (nCol == nSrcWidth-1) nColNext = nColPrev;

if ((nRow % 2) == 0) { // even row
if ((nCol % 2) == 0) { // even column, Raw Green
pDstRow[k] = ((long)pSrcRow[nColNext] + pSrcRow[nColPrev]) / 2; // Red
pDstRow[k + 1] = pSrcRow[nCol]; // green
pDstRow[k + 2] = ((long)pSrcRowNext[nCol] + pSrcRowPrev[nCol]) / 2; // blue
} else { // odd column, Raw Red
pDstRow[k] = pSrcRow[nCol]; // Red
pDstRow[k + 1] = ((long)pSrcRow[nColPrev] + pSrcRow[nColNext] + pSrcRowNext[nCol] + pSrcRowPrev[nCol]) / 4; // Green
pDstRow[k + 2] = ((long)pSrcRowNext[nColNext] + pSrcRowNext[nColPrev] + pSrcRowPrev[nColNext] + pSrcRowPrev[nColPrev]) / 4; // blue
}
} else { // odd row
if ((nCol % 2) == 0) { // even column, Raw Blue
pDstRow[k] = ((long)pSrcRowNext[nColNext] + pSrcRowNext[nColPrev] + pSrcRowPrev[nColNext] + pSrcRowPrev[nColPrev]) / 4; // Red
pDstRow[k + 1] = ((long)pSrcRow[nColPrev] + pSrcRow[nColNext] + pSrcRowNext[nCol] + pSrcRowPrev[nCol]) / 4; // Green
pDstRow[k + 2] = pSrcRow[nCol]; // blue
} else { // odd column, Raw Green
pDstRow[k] = ((long)pSrcRowNext[nCol] + pSrcRowPrev[nCol]) / 2; // Red
pDstRow[k + 1] = pSrcRow[nCol]; // Green
pDstRow[k + 2] = ((long)pSrcRow[nColNext] + pSrcRow[nColPrev]) / 2; // blue
}
}
}

pSrcRow += nSrcBytesPerRow;
pDstRow += nDstBytesPerRow;
}

return 0;
}

wysota
19th April 2010, 09:10
Please don't start multiple threads on the same subject. Threads merged.

faldzip
19th April 2010, 11:20
So the problem is your camera :]
The most important part of image processing is image acquisition. Even the best algorithms can't help you if the image quality is poor. And I don't mean only resolution, but also colors, lights which means generaly a quality of the whole scene you make a picture of. Next thing is that the light sensitive matrix (or how the hell is it called in english) in your camera is not the one that will give you the quality you want (generally those megapixels are some kind of cheat because 1 pixel can measure only 1 color (red, gree, blue) so to have color pixels camera needs 2x2 square where it takes 2 green pixels, 1 red, 1 blue and uses interpolation to get RGB values of each pixel).

So what you can do is a technique which was advised on Qt Labs: if you want to scale some image to for example a little bit less than 1/2 of original resolution, then scale it to 1/2 (which is fast and nice for an obvous reasons :] - take every second row and then every second pixel in thise rows) with a fast transformation and then use smooth transformation to get the final ratio.

ness
19th April 2010, 11:26
I you scale down an image without smoothing you may have aliasing (see image processing theory) and the grid I see on images makes me think you have aliasing !
The more your original image has noise, the more aliasing could be a problem. Try to smooth (filter) the image before scaling.

wysota
19th April 2010, 11:37
I you scale down an image without smoothing you may have aliasing (see image processing theory) and the grid I see on images makes me think you have aliasing !
The more your original image has noise, the more aliasing could be a problem. Try to smooth (filter) the image before scaling.

I don't think so. Aliasing can only occur in diagonal directions. What we see here looks more like interlace or something like that. If you scale by 1/2, 1/4, etc. the interlace will go away because all the "interlaced" lines will be discarded. Where the interlace-like effect comes from? I have no idea, probably the data aquisition process was incorrect (format conversion can be treated as part of the aquisition as well). If QImage::scaled() was not working, the effect would be noticable on the whole area of the photo and not only in some special conditions.

faldzip
19th April 2010, 11:46
o... didn't check your previous code but I see thats the thing I mentioned above with those cameras :] but didn't think you have to do it by yourself ;]

wesley
20th April 2010, 08:07
this problem is true for my other camera chips, like ov5620 which producted by OV ..

wysota
20th April 2010, 10:56
Can you replicate it with some arbitrary image downloaded from the Web?

wesley
20th April 2010, 16:42
Can you replicate it with some arbitrary image downloaded from the Web?

No, i tried to load the image got from web into a QImage, then scale and display it, There is not the "raster" problem.

wysota
20th April 2010, 17:07
But did you do the same conversion you have been doing for your image?

wesley
26th April 2010, 06:35
But did you do the same conversion you have been doing for your image?

no, because the conversion is used to convert a raw image data to RGB data, but the web image is already RGB (load with QImage)

wysota
26th April 2010, 09:42
Well, obviously QImage::scaled() works in general so you don't have to check that. Find a raw image, convert it using your routine (to test your routine) and then pass it through QImage::scaled() to see if you obtain a similar effect.