Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Using QImage.constBits(), RGB_888, and the actual pixel format seems wrong.

Using QImage.constBits(), RGB_888, and the actual pixel format seems wrong.

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.5k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • enjoysmathE Offline
    enjoysmathE Offline
    enjoysmath
    wrote on last edited by
    #1
    def subimageSearch(img, subimg, center=False):
            img = img.convertToFormat(QImage.Format_RGB888)
            subimg = subimg.convertToFormat(QImage.Format_RGB888)
            x = c_int(-1)
            y = c_int(-1)
            xptr = addressof(x)
            yptr = addressof(y)
            # ptr = ctypes.cast(addr, INTP
            imgBuf = c_void_p(img.constBits().__int__())
            subBuf = c_void_p(subimg.constBits().__int__())
            w = c_int(img.width())
            h = c_int(img.height())
            sw = c_int(subimg.width())
            sh = c_int(subimg.height())
            _libc.subimageSearch(imgBuf, w, h, subBuf, sw, sh, xptr, yptr)
            if not center:
                    return x.value, y.value
            return int(x.value + subimg.width() / 2 + 0.5), int(y.value + subimg.height() / 2 + 0.5)
    
    subimageSearch(QImage("screenshot.png"), QImage("red_pixel.png"))
    

    With the attached "screenshot.png" and "red_pixel.png" (a 4x4 red square made in MS Paint).

    The bytes that the debugger is showing for both img and subimg are:

    subimg	0x0621a538 "í\x1c$í\x1c$\x17\x6í\x1c$í\x1c$!\x6q¸‘ý\\\x2"	unsigned char *
        img	0x0621b768 "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí\x1c$í\x1c$ÿÿÿÿÿÿí\x1c$í\x1c$ate"	unsigned char * 
    

    The y's with umlaut over them are correct as that is the character 255, and those pixels are indeed white. But the rest doesn't make since: the pixels should be pure red: 255, 0, 0 = rgb.

    The debugger is on the Visual Studio side while my calling app is on the python side, and I'm using c_types to convert the types between python and the DLL function arguments, but that shouldn't matter.

    Any idea what is going on ?

    Here are teh images (they're really small):

    1_1512850683605_screenshot.png 0_1512850683605_red_pixel.png

    https://github.com/enjoysmath
    https://math.stackexchange.com/users/26327/exercisingmathematician

    K 1 Reply Last reply
    0
    • enjoysmathE enjoysmath
      def subimageSearch(img, subimg, center=False):
              img = img.convertToFormat(QImage.Format_RGB888)
              subimg = subimg.convertToFormat(QImage.Format_RGB888)
              x = c_int(-1)
              y = c_int(-1)
              xptr = addressof(x)
              yptr = addressof(y)
              # ptr = ctypes.cast(addr, INTP
              imgBuf = c_void_p(img.constBits().__int__())
              subBuf = c_void_p(subimg.constBits().__int__())
              w = c_int(img.width())
              h = c_int(img.height())
              sw = c_int(subimg.width())
              sh = c_int(subimg.height())
              _libc.subimageSearch(imgBuf, w, h, subBuf, sw, sh, xptr, yptr)
              if not center:
                      return x.value, y.value
              return int(x.value + subimg.width() / 2 + 0.5), int(y.value + subimg.height() / 2 + 0.5)
      
      subimageSearch(QImage("screenshot.png"), QImage("red_pixel.png"))
      

      With the attached "screenshot.png" and "red_pixel.png" (a 4x4 red square made in MS Paint).

      The bytes that the debugger is showing for both img and subimg are:

      subimg	0x0621a538 "í\x1c$í\x1c$\x17\x6í\x1c$í\x1c$!\x6q¸‘ý\\\x2"	unsigned char *
          img	0x0621b768 "ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿí\x1c$í\x1c$ÿÿÿÿÿÿí\x1c$í\x1c$ate"	unsigned char * 
      

      The y's with umlaut over them are correct as that is the character 255, and those pixels are indeed white. But the rest doesn't make since: the pixels should be pure red: 255, 0, 0 = rgb.

      The debugger is on the Visual Studio side while my calling app is on the python side, and I'm using c_types to convert the types between python and the DLL function arguments, but that shouldn't matter.

      Any idea what is going on ?

      Here are teh images (they're really small):

      1_1512850683605_screenshot.png 0_1512850683605_red_pixel.png

      K Offline
      K Offline
      kenchan
      wrote on last edited by
      #2

      @enjoysmath Can't see any screen shots??

      1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @kenchan The two small red dots just above the miniature of your avatar at the bottom of the post.

        Interested in AI ? www.idiap.ch
        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

        K 1 Reply Last reply
        1
        • SGaistS SGaist

          @kenchan The two small red dots just above the miniature of your avatar at the bottom of the post.

          K Offline
          K Offline
          kenchan
          wrote on last edited by
          #4

          @SGaist Aha is see them now.

          1 Reply Last reply
          0
          • enjoysmathE Offline
            enjoysmathE Offline
            enjoysmath
            wrote on last edited by enjoysmath
            #5

            This might have to do with BMP format's row padding to a multiple of 4-bytes but that doesn't explain how red comes up as far from 255,0,0

            https://github.com/enjoysmath
            https://math.stackexchange.com/users/26327/exercisingmathematician

            1 Reply Last reply
            0
            • enjoysmathE Offline
              enjoysmathE Offline
              enjoysmath
              wrote on last edited by
              #6

              It had to do with the padding. See wikipedia article on BMP format which I believe is used as the memory representation of pixels. Also, check mspaint and make sure you're using pure Red, I was not... -_- Save as BMP and double check using a hex editor on the file.

              Here's my pixel search code if anyone needs it:

              // SubimageSearch.cpp : Defines the exported functions for the DLL application.
              //
              
              #include "stdafx.h"
              #include "SubimageSearch.h"
              
              // Works with format RGB888
              
              struct Pixel {
              public:
              	unsigned char r, g, b;
              public:
              	Pixel() {
              		r = 0;  g = 0;  b = 0;
              	}
              
              	Pixel(unsigned char* img, int w, int x, int y)
              	{
              		int pad = (4 - ((w * 3) % 4)) % 4;
              		unsigned char* px = &img[(w * y + x) * 3 + y * pad];
              		r = px[0];  g = px[1];  b = px[2];
              	}
              
              	bool operator == (const Pixel& px)
              	{
              		return r == px.r && g == px.g && b == px.b;
              	}
              };
              
              // This is an example of an exported function.
              extern "C" {
              	__declspec(dllexport) void subimageSearch(unsigned char* img, int w, int h, unsigned char* subimg, int sw, int sh, int* foundX, int* foundY)
              	{
              		Pixel px, px1 = Pixel(subimg, sw, 0, 0);
              
              		for (int y=0; y < h - sh + 1; y++) {
              			for (int x = 0; x < w - sw + 1; x++) {
              				px = Pixel(img, w, x, y);
              
              				if (px == px1) {
              					for (int y1 = 0; y1 < sh; y1++) {
              						for (int x1 = 0; x1 < sw; x1++) {
              							px = Pixel(img, w, x + x1, y + y1);
              							px1 = Pixel(subimg, sw, x1, y1);
              
              							if (!(px == px1)) {
              								goto not_found;
              							}
              						}
              					}
              					*foundX = x;
              					*foundY = y;
              					return;
              
              				not_found:
              					px1 = Pixel(subimg, sw, 0, 0);
              					continue;
              				}
              			}
              		}
              	}
              }
              

              Notice the pad computation added in.

              https://github.com/enjoysmath
              https://math.stackexchange.com/users/26327/exercisingmathematician

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved