Как программисты ищут отличия



    Часто за собой замечаю, что при виде какой-нибудь программы, игры или сайта у меня возникают странные мысли. И мысли эти меня пугают. А думаю я всякий раз о том, как эту программу/сайт/игру можно подхачить, взломать, обойти защиту, автоматизировать, расширить функциональность. Наверное, профессиональная деформация дает о себе знать. Или это подсознательное желание использовать накопленные знания, не находящие применения на работе. Как правило, эти желания остаются на уровне мыслей, но бывают исключения. Об одном таком случае я и расскажу вам сегодня…

    Было это давно. Году, эдак, в 2008. Был обычный зимний день. Ничего не предвещало бессонной ночи. Но тут я заметил, как будущая жена играет на компе в одну игру…


    То была игра «Найди 5 отличий» (в оригинале «5 Spots»). При виде пользовательского интерфейса игры у меня сразу возникло вышеуказанное желание — «А можно ли написать программу, которая бы искала отличия и подсказывала игроку куда жать мышкой, а то и сама бы двигала ей и жала сама?». Как оказалось, возможно все.

    Сама игра довольно старая и примитивная. Как видно из скриншота, она показывает 2 картинки с отличиями и ждет пока юзер прокликает их мышкой. Все просто. Такой подход избрал и я в своем решении:
    1. юзер запускает программу-подсказчика (ПП)
    2. запускает целевую игру
    3. жмет волшебную комбинацию клавиш
    4. в нужным местах картинки ПП подсвечивает различия

    Мне нравится, когда программы разговаривают со мной: пишут логи, отчитываются о своих действиях, сообщают об ошибках. Тогда создается впечатление, что программа не бездушный сухой алгоритм, просто делающий свою работу, а живой организм. Он может быть молчаливым, изредка выводящим сообщения, либо разговорчивым, активно фигача в консоль…


    В общем, я выбрал консольное приложение как основу для ПП. Зарегистрировал комбинацию горячих клавиш Ctrl + F1 (типа, «помощь»), повесил обработчик. Но как найти отличия в 2х картинках из игры? Для начала, картинки нужно было «увидеть» программно. Тут тоже все просто — «фотографируем» окно в фокусе в память по нажатию на горячие клавиши:

    Фотографирование экрана
        HWND targetWindow = ::GetForegroundWindow();
        HDC targetWindowDC = ::GetWindowDC(targetWindow);
        if (targetWindowDC != NULL)
        {
            HDC memoryDC = ::CreateCompatibleDC(targetWindowDC);
            if (memoryDC != NULL)
            {
                CRect targetWindowRectangle;
                ::GetWindowRect(targetWindow, &targetWindowRectangle);
    
                HBITMAP memoryBitmap = ::CreateCompatibleBitmap(targetWindowDC, targetWindowRectangle.Width(), targetWindowRectangle.Height());
                if (memoryBitmap != NULL)
                {
                    ::SelectObject(memoryDC, memoryBitmap);
                    ::BitBlt(memoryDC, 0, 0, targetWindowRectangle.Width(), targetWindowRectangle.Height(), targetWindowDC, 0, 0, SRCCOPY);
    



    Позиции картинок с отличиями в игре постоянные, размеры окна игры тоже — поэтому тут решает хардкод смещений и размеров (ведь наша ПП работает только с этой игрой). В памяти берем 2 картинки и «ксорим» их одна на другую:
    XOR двух половинок
                    #define BITMAP_WIDTH 375
                    #define BITMAP_HEIGHT 292
    
                    #define COORD_X_LEFT_IMAGE_UPPER_LEFT 19
                    #define COORD_Y_LEFT_IMAGE_UPPER_LEFT 152
    
                    #define COORD_X_RIGHT_IMAGE_UPPER_LEFT 405
                    #define COORD_Y_RIGHT_IMAGE_UPPER_LEFT COORD_Y_LEFT_IMAGE_UPPER_LEFT
    
                    ::BitBlt(
                        memoryDC, 
                        COORD_X_LEFT_IMAGE_UPPER_LEFT, 
                        COORD_Y_LEFT_IMAGE_UPPER_LEFT, 
                        BITMAP_WIDTH, 
                        BITMAP_HEIGHT, 
                        memoryDC, 
                        COORD_X_RIGHT_IMAGE_UPPER_LEFT, 
                        COORD_Y_RIGHT_IMAGE_UPPER_LEFT, 
                        SRCINVERT
                        );
    



    ВыXORивается следующая картина:


    А дальше начинается поиск отличий.

    Сейчас, когда пишу эту статью, вспоминаю, что была у меня какая-то либо лаба, либо курсовой проект в универе на эту тему. На тему обработки похожих изображений. И там я написал этот алгоритм. Я прекрасно понимаю, что ничего нового не изобрел — скорее всего, у этого алгоритма даже есть какое-то специальное название. Да и не привязан он к изображениям вовсе. В общем, кто знает, что это, подскажите.

    Итак, мы имеет черную картинку с нечерными пикселями в местах, где были отличия. Причем пиксели эти расположены не вплотную друг к другу, а, в общем случае, с какими-то промежутками. Но, как видно из скриншота, области отличий достаточно локализованы. Алгоритм поиска этих областей состоит в следующем:
    1. проходим по картинке
    2. находим нечерный пиксель
    3. смотрим в его окрестность и ищем его нечерных соседей — все это помещаем в найденную область (если рассматриваемые пиксели не были обработаны ранее)

    Настраиваемым параметром тут служит «размер» окрестности пикселя — на сколько далеко можно от него заглядывать. Это позволяет искать более «размазанные» области отличий. Понятное дело, что все это неидеально и, в общем случае, найденных областей будет больше, чем отличий в картинках — ведь в самих картинках-заданиях возможен шум от сжатия, затесавшийся курсор мыши или что-то еще, выглядещее как различие на программном уровне, но незаметное с точки зрения игрока. Поэтому найденные различия нужно отсортировать по площади — чем больше нечерных пикселей вмещает область, тем больше вероятность того, что это не шум, а именно различие.

    Уже потом я узнал и попробовал OpenCV (возможно, и о ней будет статья). Думаю, что есть более быстрые и оптимизированные алгоритмы. Но тогда меня хватило именно на такой вариант.


    Исходник поиска различий (код старый, публикую без изменений):
    Поиск различий
    #include "StdAfx.h"
    #include ".\bitmapinfo.h"
    #include <stack>
    
    const CPixel CBitmapInfo::m_defaultPixel;
    
    CBitmapInfo::CBitmapInfo(void)
    {
        m_uWidth = 0;
        m_uHeight = 0;
    }
    
    CBitmapInfo::~CBitmapInfo(void)
    {
        Clear();
    }
    
    HRESULT CBitmapInfo::Clear()
    {
        m_uWidth = 0;
        m_uHeight = 0;
    
        // Pixel clearing
        for (CPixelAreaIterator pixelAreaIterator = m_arPixels.begin(); pixelAreaIterator != m_arPixels.end(); ++pixelAreaIterator)
        {
            delete (*pixelAreaIterator);
        }
        m_arPixels.clear();
    
        return S_OK;
    }
    
    HRESULT CBitmapInfo::LoadBitmap(HDC hDC, const CRect &bitmapRect)
    {
        Clear();
    
        m_uWidth = bitmapRect.Width();
        m_uHeight = bitmapRect.Height();
    
        m_arPixels.assign(m_uHeight * m_uWidth, NULL);
    
        for (INT nPixelY = 0; nPixelY < m_uHeight; ++nPixelY)
        {
            for (INT nPixelX = 0; nPixelX < m_uWidth; ++nPixelX)
            {
                CPixel *pPixel = new CPixel(nPixelX, nPixelY, ::GetPixel(hDC, nPixelX + bitmapRect.left, nPixelY + bitmapRect.top));
                SetPixel(nPixelX, nPixelY, pPixel);
            }
        }
    
        return S_OK;
    }
    
    HRESULT CBitmapInfo::GetPixelAreas(INT nPixelVicinityWidth, CPixelAreaList &arPixelAreaList)
    {
        arPixelAreaList.clear();
    
        if (m_uHeight > 0)
        {
            // Reinitialize all pixel reserved values (if needed)
            const CPixel *pFirstPixel = GetPixel(0, 0);
            if (pFirstPixel->IsValid() != FALSE && pFirstPixel->GetReserved() != CBitmapInfo::m_defaultPixel.GetReserved())
            {
                for (INT nPixelY = 0; nPixelY < m_uHeight; ++nPixelY)
                {
                    for (INT nPixelX = 0; nPixelX < m_uWidth; ++nPixelX)
                    {
                        CPixel *pPixel = GetPixel(nPixelX, nPixelY);
                        pPixel->SetReserved(-1);
                    }
                }
            }
    
            // Process pixels
            typedef stack<CPixel*> CPixelStack;
    
            // Look through all bitmap pixels
            const UINT uPixelCount = m_uWidth * m_uHeight;
            UINT uPixelAreaIndex = 0;
            for (INT nPixelY = 0; nPixelY < (INT)m_uHeight; ++nPixelY)
            {
                for (INT nPixelX = 0; nPixelX < (INT)m_uWidth; ++nPixelX)
                {
                    CPixel *pPixel = GetPixel(nPixelX, nPixelY);
    
                    // If this pixel is valid (belongs to bitmap)
                    if (pPixel->IsValid() != FALSE)
                    {
                        // If this current pixel is not already processed
                        if (pPixel->GetReserved() == CBitmapInfo::m_defaultPixel.GetReserved())
                        {
                            // Set this pixel as processed
                            pPixel->SetReserved(uPixelAreaIndex);
    
                            // If this pixel matches localization criteria
                            if (pPixel->GetColor() != COLOR_BITMAP_BACKGROUND)
                            {
                                // Add pixel to its area
                                CPixelArea *pPixelArea = new CPixelArea();
                                pPixelArea->push_back(pPixel);
    
                                // Push pixel to its stack
                                CPixelStack pixelStack;
                                pixelStack.push(pPixel);
    
                                do 
                                {
                                    CPixel *pVicinityPixel = pixelStack.top();
                                    pixelStack.pop();
    
                                    INT nStartingX = pVicinityPixel->GetX();
                                    INT nStartingY = pVicinityPixel->GetY();
                                    for (INT nVicinityY = nStartingY - nPixelVicinityWidth; nVicinityY <= nStartingY + nPixelVicinityWidth; ++nVicinityY)
                                    {
                                        for (INT nVicinityX = nStartingX - nPixelVicinityWidth; nVicinityX <= nStartingX + nPixelVicinityWidth; ++nVicinityX)
                                        {
                                            pVicinityPixel = GetPixel(nVicinityX, nVicinityY);
    
                                            // If this pixel is valid (belongs to bitmap)
                                            if (pVicinityPixel->IsValid() != FALSE)
                                            {
                                                // If this current pixel is not already processed
                                                if (pVicinityPixel->GetReserved() == CBitmapInfo::m_defaultPixel.GetReserved())
                                                {
                                                    // Set this pixel as processed
                                                    pVicinityPixel->SetReserved(uPixelAreaIndex);
    
                                                    // If this pixel matches localization criteria
                                                    if (pVicinityPixel->GetColor() != COLOR_BITMAP_BACKGROUND)
                                                    {
                                                        pPixelArea->push_back(pVicinityPixel);
                                                        pixelStack.push(pVicinityPixel);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                } while (pixelStack.size() > 0);
    
                                arPixelAreaList.push_back(pPixelArea);
                                ++uPixelAreaIndex;
                            }
                        }
                    }
                }
            }
        }
    
        return S_OK;
    }
    



    Дальше еще проще — подсветить найденные области на экране. Так как программа игры не использует никаких DirectX'ов (на сколько я могу судить), то тут помог простой вывод графики на окно игры. В общем-то, если бы был DirectX, то так просто «сфоткать» экран не получилось бы, не говоря уже о подсветке различий поверх игры. Но тут WinAPI рулит (функция ::Rectangle()). Результат подсветки:



    От полностью программной игры пришлось отказаться — ПП и так слишком облегчала игру, если бы она еще и за тебя играла, то было бы вообще неинтересно. Но докрутить ПП до бота проще простого — зная координаты областей-отличий можно прокликать их мышкой, дождаться следующего уровня, распознать отличия и так далее…

    Это все возможно, но, судя по всему, тогда меня хватило только на одну бессонную ночь.
    Поделиться публикацией

    Похожие публикации

    Комментарии 88

    • НЛО прилетело и опубликовало эту надпись здесь
        +19
        Вы, наверное, про технику просмотра 3д-картинок. Честно признаюсь, у меня почти никогда не получалось их увидеть. В школе думал, что одноклассники надо мной издеваются, подкидывая «нерабочие» картинки…
          +9
          Ну да, техника та же самая. Сейчас потестил: и правда очень легко отличия находятся.
            +21
            Попробуйте обратный вариант — скосите глаза к носу. Это легче. Я тоже так находил в детстве отличия) Но это дикий чит. Отличия тупо светиться начинают.
              +2
              То есть прямой вариант — это развести глаза от носа? :) Так вот почему у меня все детство ничего не получалось. Оно и хорошо, наверное.
                0
                Ну, ничего плохого не случилось бы. Даже наоборот: хорошая тренировка для глаз.
                  +9
                  О, кстати, завтра новая статья из моего цикла про лазерную коррекцию будет. Финальная. Я еще думаю. включать ли упражнения туда. Уж больно перегружено будет. Наверное стоит отдельной статьей.
                    +2
                    Стоит, тут аудитория подходящая :)
                      +7
                      Я вот больше склоняюсь к отдельной большой статье) По гигиене труда и упражнениям. Ладно, пошел спать. Завтра после 9 выложу)
                        0
                        обоими руками за упражнения и если будет по гигиене труда, то вообще супер!
                        мы тут недавно на работе лайфхак для ноутбуков придумали [хотя возможно мы не первые]. рабочие столы — обычные офисные столы, и если ставить на них ноут, то экран находится значительно ниже уровня глаз. подставили под ноуты небольшие коробки — если есть usb мышь и клавиатура, то вполне сносно
                  +4
                  О… У меня еще веселее было. Я с детства умел глаза конвергировать — к носу. И мучался от того, что вижу 3D картинки вывернутыми наизнанку по оси Z. Только спустя лет 5 понял, что у меня была обратная техника. Надо дивергировать — разводить глаза от носа. Такое происходит, когда вы смотрите вдаль. Довольно легко тренируется на заборе с повторяющимся рисунком-высечкой. Смотрите на предметы за забором, а он начинает двоиться, при этом одинаковые элементы сливаются.

                  Сейчас я могу эти картинки почти под любым углом видеть за 3-5 секунд
                    +2
                    У нас на потоке учится парень, так тот вообще глазами как хочет вертит. Выглядит довольно забавно, хотя порой жуть берёт от того, как он их вывернет. Зато на зрение не жалуется.
                      +4
                      Я с детства умел глаза конвергировать — к носу. И мучался от того, что вижу 3D картинки вывернутыми наизнанку по оси Z.
                      о_О Погодите. То есть я вижу, что в «волшебных картинках» действительно изображена какая-то фигня, но то что я никогда не мог понять, что именно изображено, это из-за того, что картинка инвертирована?
                        +9
                        Вы объем видите? Если видите четкие формы, но не понимаете что это, то вероятно у вас ось инвертирована. Проверьте простых объектах типа шара. Попробуйте картинку ниже. Простая геометрия.


                        Если вы смотрите правильно — там типа кратера вулкана. Если неправильно — выпуклая полусфера в яме.
                          +2
                          Я свожу глаза (т.е. фокус перед картинкой) и вижу кратер. ЧЯДНТ?

                          ЗЫ: Эмм. Вру. Таки фокус за картинкой, все верно )
                            0
                            Вы видите яму, в которой шар лежит в центре? центральная точка выше или ниже окружения?
                              0
                              Вижу кратер, по ощущениям казалось, что свожу глаза, но перепроверил, проведя пальцем от переносицы к картинке — нигде палец не попал в фокус — значит фокус за картинкой, и мои ощущения меня подвели.
                                0
                                Я вот тоже вижу выпуклую гору и огромную яму в ней. Лежит ли в яме шар, я не пойму. При этом я могу двигать головой в стороны, картинка смещается. Второй вопрос не понял — о чём он?
                                  0
                                  И то, о чём вы пишете ниже — двойную дивергенцию тоже сумел, а шар нет. Это что, я получается, всю жизнь видел неправильные стереокартинки? о_О

                                  upd: А, нет, сообразил. Не сразу заметил подпись под картинкой. Кратер — правильно. Успокоился… Но теперь очень хочу попробовать увидеть шар :)
                                    +2
                                    Скосите глаза к носу, будто дурачитесь, и так посмотрите на картинку. :) В какой-то момент получится.

                                    А я вот всю жизнь смотрела неправильно — глазами к носу — и видела углубления. Только что посмотрела «сквозь монитор» — и впервые в жизни увидела правильно. Рассматриваю теперь книжку с 3D-картинками. )
                              +2
                              Ох. Сколько, пять лет, говорите, потребовалось?

                              У меня никогда не получалось дивергировать (я даже слова-то такого до сегодня не знал), зато получалось конвергировать. Видел объём, думал — вот, классно, умею смотреть такие картинки. А то, что не могу разглядеть, что там, так это картинки неправильные. А оно вот оно как…

                              Сейчас попробовал — получилось увидеть и кратер. Но состояние неустойчивое, чуть шевельнусь — и всё пропадает.
                                +2
                                Пять лет потребовалось на понимание моей ошибки) Потом быстро.
                                  +1
                                  Тоже страдаю подобной фигней. Но тут Meklon написал выше, что можно тренировать фокусировать взгляд за картинкой, и щас тридцать минут мучался, но-таки сфокусировал фокус ЗА картинкой.
                                  +1
                                  Не к месту, но вспомнилась танцующая балерина.
                                    +1
                                    Вот со стереокартинками у меня никогда ничего не получалось. А эту балерина довольно быстро научился вертеть во все стороны. И вот почему так?
                                    +1
                                    Хм, никогда не пробовал фокусироваться перед картинкой. Сейчас попробовал — получилось. Теперь могу по желанию видеть поочередно то кратер, то шар в яме :)
                                      0
                                      Если сделать двойную конвергенцию получается какая-то порнография) Особенно с учетом цвета фона)
                                      +10
                                      Моя любимая стереокартинка.
                                      image

                                      А еще, я 3D-фильмы смотрю перекрестным методом, правда, после 20 минут просмотра глаза уже сильно устают.

                                      На youtube много всяких роликов в 3d. В настройках плеера нужно указать режим «Без очков».
                                        0
                                        а вот моя любимая: image
                                          +1
                                          Но это неправильные картинки! В них используется конвергенция, и глаза очень напрягаются и устают.
                                          Вот версии этих же картинок для дивергенции (сразу говорю, используя дивергенцию, их сложно свести в один 3D-кадр):
                                          Скрытый текст

                                            0
                                            Конвергенцией получается ерунда :)
                                            А дивергировать не получается, картинки сходятся лишь на пару см…
                                              +1
                                              Тренируйтесь, и да пребудет с вами Сила дивергенции!
                                              0
                                              а мне как раз сложней смотреть на ваши
                                                +2
                                                Ничего сложного. Но эти картинки лучше верхних смотрятся.
                                                  0
                                                  Спасибо! А то я уже было подумал, что со мной что-то не так, когда никак не мог уловить объем привычным способом :)
                                                    0
                                                    Оказывается, я умею и конвергировать и дивергировать как бы «автоматически», не замечая для себя различий между этими способами ) т.е. и на неправильных и на правильных картинках я вижу одну и ту же 3d-картину. Правда, на неправильных это сделать чуть сложнее, и глаза сильнее напрягаются, тут вы правы.
                                                    Раньше для меня было загадкой, почему некоторые картинки смотреть сложнее, чем остальные, спасибо за пояснения :)
                                                      0
                                                      Это как это «одну и ту же 3d-картину». Не может такого быть. Если в стерео-паре поменять местами каналы (а именно это и происходит когда «неправильно» смотришь), то картинка получается вывернутой наизнанку по глубине.
                                                      Сам без каких-либо напряжений могу и так и так смотреть. Но разница видна сразу, если что-то не так сделал.
                                                      Главное чтобы картинки не стояли слишком далеко друг от друга, а то иногда просто физически не могу развести так глаза.
                                                        0
                                                        На примере двух картинок, которые выше — чтобы их посмотреть нормально нужно конвергировать. А вот дивергировать мне лично очень сложно, потому что ширина между парами большем, чем расстояние между оптическими осями моих глаз.
                                                        Получается, что я максимум мог направления взглядов каждого глаза отправить в параллель. Это и есть максимум ширины между стерео-парами, который я могу смотреть таким способом.
                                                  0
                                                  А что на этой картинке в итоге надо увидеть? Я пытаюсь уловить конечную форму, но не получается. Вижу только как две фигуры двигаются как бы в легком танце. Глюки не иначе!))
                                                    +2
                                                    Ну там каждый следующий персонаж перекрывает другого в 3D.
                                                  +2
                                                  я сперва кратер увидел, а потом, когда стал пытаться увидеть шар, но получилось увидеть что-то типа линзы по центру с углублением и регионов, исходящих от линзы ((()))
                                                    +6
                                                    Это двойная дивергенция. Вы словили симметрию второго порядка. Глаза развели еще сильнее и ушли в Матрицу слили вторичные элементы между собой.
                                                    +1
                                                    Наконец-то! Наконец-то я смог увидеть хоть что-то на этих картинках!
                                                      +2
                                                      Если вы увидели яму с полусферой, то задачу вы ещё не решили: теперь нужно увидеть правильную картинку :)
                                                        0
                                                        У меня глобальный вопрос, почему бы картинки не делать с обратным объёмом, ведь их так смотреть гораздо проще? Ну или в двух вариантах предлагать?
                                                          +4
                                                          Это не проще. Это вопрос привычки. Плюс обратный вариант даёт дикое переутомление, а не эффект расслабления.
                                                            +1
                                                            У людей уходят недели, чтобы научиться, против 5 минут на конвергентную стереопару. А многим так и вообще не удаётся научиться смотреть сквозь экран, тогда как фокусировать глаза перед экраном выходит у всех без исключения, и даже напрягаться не надо. Кроме того, одно дело сдвинуть картинки на сантиметр, как на изображении с кратером, и совсем другое — на полэкрана, как в 3D-фильмах. Посмотрите-ка такие фильмы с экрана, когда они в виде дивергентной стереопары. Даже вот картинку с крокодилом из поста выше «дивергировать» ох как тяжко, потом глаза минуты две вообще крайне неохотно хоть что-то в фокус берут.
                                                            Так что это не вопрос привычки, а действительно на два порядка сложнее. Всё равно что утверждать, будто бы ходить по доске шириной в 20 см., подвешенной на высоте 9 этажа, так же просто, как и по подвешенной в 5 см от земли, просто привыкнуть надо… Или что на Haskell программировать так же легко, как на Python'е и Ruby, всего-то и надо мышление перестроить. Но вот в этой-то перестройке и кроется основная сложность.
                                                              0
                                                              Это именно что вопрос привычки. Я, например, на картинке выше минут 30 пытался увидеть шар, так и не вышло. При этом вулкан виден секунды через 3.
                                                                0
                                                                Ну не знаю, отсядьте подальше от экрана, может, картинка легче сведётся. Я по ссылке на ютуб вчера полчаса залипал, скосив глаза. Если отсесть подальше, смотреть можно, но поле зрения маленькое.
                                                            0
                                                            там типа кратера вулкана.

                                                            Я смог там такое увидеть.
                                                          +2
                                                          Вот чёрт :-(
                                                  0
                                                  я вас научу.
                                                  Смотрите на палец и приближаете его к носу. На заднем плане должна быть картинка. Эта картинка начнет двоиться и в какой-то момент соседние картинки сольются в одну
                                                    +1
                                                    Не учите неправильно. Это инвертированный вариант с конвергенцией. habrahabr.ru/post/224727/#comment_7649897
                                                      0
                                                      А у меня никак не получается. Вижу размазню только, и всё… хоть ближе фокусировать, хоть дальше — без разницы.
                                                        +1
                                                        Не торопитесь. Расслабьтесь. Главное поймать это движение мышц при переводе взгляда в бесконечность
                                                          0
                                                          Не пойму, если я начинаю разводить/сводить глаза — вся картинка становится не в фокусе (в т.ч. и экран ноутбука). Как при этом можно увидеть что-то? Оно ж размытое всё.
                                                          Наверное, я что-то не так делаю…
                                                            0
                                                            Продолжайте мучаться, щас тридцать минут страдал, и увидел кратор, надо играть с фокусным расстоянием За картинкой, больше/меньше
                                                              0
                                                              а некоторые бога видят…
                                                              0
                                                              Все правильно. Когда идет процесс раздвоения картинка сначала может быть размытой, но когда все совпадет, глаза поймают картинку и сфокусируются. И тогда все станет четко и понятно.
                                                                +3
                                                                Для всех отчаявшихся, у которых не получается дивергировать:
                                                                1. Упираетесь кончиком носа в картинку
                                                                2. Расслабляете глаза, при этом создается впечатление «погружения»
                                                                3. Начинаете отдаляться от картинки
                                                                4. Наслаждаетесь результатом дивергируете
                                                                Плюс это забавно смотрится в офисе, когда сотрудники тыкаются носом в экраны)
                                                                +1
                                                                Да, оно размытое, и каждый элемент двоится. То есть если у вас при обычном взгляде на картинке, скажем, два кружочка
                                                                О     О
                                                                1     2

                                                                (1 и 2 — это порядковые номера)

                                                                то при расфокусировке каждый из них раздвоится
                                                                О О   О О
                                                                1 1'  2 2'

                                                                Ваша задача свести вместе соседние и зафиксировать фокусировку в этом положении:
                                                                О     О     О
                                                                1    1'(2)  2'


                                                                В данном случае средний состоит из двух.

                                                                Удерживайте фокус в таком положении, дышите ровно, и совсем скоро периферическим зрением вы начнете выхватывать «глубину» тех или иных участков, и в конце концов увидите полную объемную картинку.
                                                                  0
                                                                  Т.е. получается что всё равно видим три картинки — одну объемную, и две по бокам? Если так, то уже лучше, я-то думал что одна должна получится в итоге.
                                                                    +2
                                                                    Если «исходника» только 2 (как в примерах выше), то да, видим 3 картинки: одну «плотную» (в центре) и 2 полупрозрачные по краям.
                                                                    А если картинка в виде повторяющегося паттерна (как в самом первом примере), то полупрозрачной будет только малая часть по бокам (шириной в один шаг паттерна), а основная часть картинки будет «плотная».
                                                                      0
                                                                      Да-да. Именно так. Объёмная центральная и две плоских по бокам.
                                                          0
                                                          У меня за монитором стена — я представила, что смотрю на неё, будто монитора нет. Только что впервые в жизни получилось увидеть правильно.
                                                          Попробуйте так же.
                                                          +20
                                                          Своим комментарием вы задели меня за живое, как человека, который смотрит на мир одним глазом .-(
                                                            +2
                                                            Не расстраивайтесь, возможно, вы еще при жизни сможете это увидеть, наука и инженерия вперед идут нехилыми шагами, тем более теперь, когда корпорации присоединились к процессу.
                                                              +3
                                                              Сочувствую. Есть надежда в ближайшие десятилетия дождаться нейроинтерфейса матрица — зрительный нерв. Будем надеяться)
                                                                +1
                                                                Это не спасет увы таких, как я, у кого глаз-то два, но мозг считает картинку с одного из них основной, а второй генерит только дополнительное периферическое изображением. Настолько я понимаю, это результат адаптации мозга к косоглазию в детствие, чтобы не видеть все время часть собственного носа. Косоглазие исправилось, а вот мозг после этого не ясно, как перепрошить :)
                                                                  0
                                                                  Я вас понимаю. Если косоглазие исправилось, то попробуйте походить с заклеенным дометанным глазом. Где-нибудь на безопасной территории (чтобы машина не сбила). Делайте это периодически. Мозг научится обрабатывать картинку со второго глаза, ибо больше её будет брать неоткуда.
                                                                  Разумеется это работает, если на втором глазу нет настоящих проблем со зрением, которые бы не позволяли ему видеть.
                                                                    0
                                                                    Картинка только со второго глаза воспринимается очень непривычно. Надо найти кучу времени для таких экспериментов, ибо работать я так точно не смогу.
                                                                      0
                                                                      Не все так просто, особенно у взрослых. У нас для этого вообще целый комплекс аппаратов для нейростимуляции.
                                                                        0
                                                                        Я когда-то читал о таком эксперименте:
                                                                        Двум подопытным (взрослым) одели линзы, через которые все было видно вверх ногами. Вот они так и пробовали жить. Спустя две недели ( по срокам могу ошибаться) подопытные стали видеть все нормально. То есть мозг адаптировался и стал переворачивать изображения.
                                                                        Когда линзы сняли, то у них опять все стало вверх ногами. Пришлось опять мучиться около двух недель, чтобы все восстановилось.

                                                                        Если это правда, то получается, что можно «перепрошить» мозг. Но это нужно делать непрерывно и достаточно долго.

                                                                        Убедитесь, что заряд устройства не менее 50%. Не выключайте и не перезагружайте устройство во время перепрошивки. (с)
                                                                          0
                                                                    +10
                                                                    Привет, коллега!
                                                                      +9
                                                                      Хорошо, что незрячие не видят тот комментарий…
                                                                        –1
                                                                        И что в этом хорошего?
                                                                          +5
                                                                          Черный юмор же.
                                                                            –4
                                                                            Хм, ок. Тогда поставьте тег в месте, где надо смеяться. Не совсем понятно…
                                                                              +2
                                                                              Можно не смеяться. Серьезно.
                                                                            +3
                                                                            Черный юмор. Или напоминание о том, что бывает и хуже.
                                                                        0
                                                                        И не подозревал о таком интересном лайфхаке. И работает же!
                                                                        +28
                                                                        «смотрим в его окрестность и ищем его нечерных соседей»

                                                                        image
                                                                          +1
                                                                          Я прям как чувствовал, что в этой фразе кто-то да найдет то, чего в ней нет. В следующий раз буду поосторожнее.
                                                                            +2
                                                                            кто-то да найдет то, чего в ней нет

                                                                            А это так и работает
                                                                          –3
                                                                          Вот уж проблемы уровня хабра — две картинки сравнить. :(
                                                                            +2
                                                                            Статья и правда кажется несколько странной, однако ваш комментарий неконструктивен и больше похож не ворчание, чем на высказывание. Кроме того, без этой статьи Хабрахабр лишился бы замечательного обсуждения техники стереоскопического зрения в комментариях выше.
                                                                            0
                                                                            Вообще, очень хорошо вопросы стереоскопии рассмотрел Перельман в первой книге «Занимательной физики», 9 глава, «Зрение одним и двумя глазами».
                                                                            Конкретно про стереоскопию можно найти тут, а слева на той же странице — навигация по главам с разбиением на части.
                                                                            P.S. Моя любимая книжка в детстве была.

                                                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                                                            Самое читаемое