Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct

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

    General and Desktop
    3
    6
    1117
    Loading More Posts
    • 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.
    • enjoysmath
      enjoysmath last edited by

      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 Reply Quote 0
      • K
        kenchan @enjoysmath last edited by

        @enjoysmath Can't see any screen shots??

        1 Reply Last reply Reply Quote 0
        • SGaist
          SGaist Lifetime Qt Champion last edited by

          @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 Reply Quote 1
          • K
            kenchan @SGaist last edited by

            @SGaist Aha is see them now.

            1 Reply Last reply Reply Quote 0
            • enjoysmath
              enjoysmath last edited by enjoysmath

              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 Reply Quote 0
              • enjoysmath
                enjoysmath last edited by

                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 Reply Quote 0
                • First post
                  Last post