Определить линию белых пикселей на изображении в Objective-c (Какао) - PullRequest
0 голосов
/ 27 мая 2011

Я создаю приложение, которое использует изображения из веб-сервиса.К сожалению, изображения дополняются белым (когда сервис изменил их размер, давным-давно).

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

В общем, я думаю: - Пробежаться по горизонтальным линиям (полная ширина и высота 1 пиксель) и проверить, имеет ли он одинаковый белый нюанс по всему.

(чтобы потом оптимизировать, я мог бы определить цвет по определению первого и последнего пикселя, и если они совпадают, проверить на полпути и т. Д.) - Не важно в первом наброске.размер обивки.Изображения имеют различные размеры и пропорции и дополняются до одинакового размера.Таким образом, границы дополнения меняются от изображения к изображению.

РЕДАКТИРОВАТЬ: Вот один: http://i.dbastatic.dk/images/3/37//74438337_30052011063215_9539_3.jpg и вертикальный: http://i.dbastatic.dk/images/3/40//74273140_23052011090107_0806_3.jpg и хитрый: http://i.dbastatic.dk/images/3/61/500396561_27052011171605_5877_3.jpg обратите внимание, что последнийимеет частично белый фон, поэтому мне нужно определить, распределяются ли пиксели белого цвета по всей ширине изображения.

Не могли бы вы дать мне пример кода для начала.Трудная часть, я думаю, состоит в том, чтобы пробежать по изображению попиксельно и определить цвет.

Может быть, C ++ будет гораздо быстрее, чем его?

Я способен на оба C ++и Objective-C, так дайте мне ваш лучший шанс: -)

Ответы [ 2 ]

1 голос
/ 27 мая 2011
NSImage* yourImage;
NSBitmapImageRep *bitmapRep = [NSBitmapImageRep imageRepWithData:[yourImage TIFFRepresentation]];

unsigned char* pixelData = [bitmapRep bitmapData];

Пиксели, вероятно, в формате RGB, поэтому отсюда должно быть легко проходить изображение пиксель за пикселем.

Вы можете проверить формат данных:

int depth       = [bitmapRep bitsPerSample];
int channels    = [bitmapRep samplesPerPixel];
int height      = [bitmapRep size].height;
int width       = [bitmapRep size].width;

РЕДАКТИРОВАТЬ : Для проверки утверждений Ваджиха я написал небольшую (быструю и грязную) тестовую программу, но мне нужна некоторая помощь для определения границы с преобразованием Хафа, хотя:EDIT2 : я понял, что Wajih имел в виду специальную реализацию преобразования Хафа (kht) (не версия OpenCV), у меня нет измерения времени для kht.Я обновил исходный код для обработки артефактов сжатия jpg.

std::string origFileName("../data/500396561_27052011171605_5877_3.jpg");
cv::Mat image = cv::imread(origFileName, 0);

std::cout << __PRETTY_FUNCTION__ << " -- widht, height = " << image.cols << ", " << image.rows << std::endl;

QElapsedTimer naiveTimer;
naiveTimer.start();
unsigned int x1 = 0;
unsigned int y1 = 0;
unsigned int x2 = 0;
unsigned int y2 = 0;

const unsigned int thresholdColor = 15; // how much may the color deviate
const unsigned int thresholdPixel = 5;  // how many false detections do you want to tolerate

for (unsigned int ii = 0; ii < 1000; ++ii)
{
    x1 = y1 = x2 = y2 = 0;
    unsigned char* pixel = image.ptr<unsigned char>(0);
    unsigned char border = *pixel;
    bool top = true;

    // horizontal border lines
    for (int yy = 0; yy < image.rows; ++yy)
    {
        pixel = image.ptr<unsigned char>(yy);
        int count = 0;
        for (int xx = 0; xx < image.cols; ++xx)
        {
            if (255 - *pixel < thresholdColor)
                ++count;

            ++pixel;
        }
        if (image.cols - count < thresholdPixel)
        {
            if (top) ++y1;
            else ++y2;
        }
        else top = false;
    }
    y2 = image.rows - y2;


    // vertical border lines
    bool left = true;
    pixel = image.ptr<unsigned char>(0);
    unsigned int offset = image.ptr<unsigned char>(1) - pixel;
    for (int xx = 0; xx < image.cols; ++xx)
    {
        int count = 0;
        unsigned char* colPixel = pixel++;
        for (int yy = 0; yy < image.rows; ++yy)
        {
            if (255 - *colPixel < thresholdColor)
                ++count;

            colPixel += offset;
        }
        if (image.rows - count < thresholdPixel)
        {
            if (left) ++x1;
            else ++x2;
        }
        else left = false;
    }
    x2 = image.cols - x2;
}

std::cout << __PRETTY_FUNCTION__ << " -- Time elapsed: " << naiveTimer.elapsed() << std::endl;
std::cout << __PRETTY_FUNCTION__ << " -- x1 y1 x2 y2: " << x1 << " " << y1 << " " << x2 << " " << y2 << std::endl;

QImage original(origFileName.c_str());
QImage cropped = original.copy(x1, y1, x2 - x1, y2 - y1);

EHVhu.jpg (изображение, которое я использовал для тестирования, кроме изображений, предоставленных esbenr): The image that I used for testing

0 голосов
/ 27 мая 2011

Что вам нужно сделать, это принять лучший и более быстрый алгоритм.Вы можете использовать алгоритмы преобразования Хафа для обнаружения линий.здесь вы можете даже установить ширину и длину обнаруживаемых линий.Эта ссылка может быть полезна Здесь .Если у вас есть опыт работы с OpenCV, вы можете использовать его встроенные быстрые методы для быстрого обнаружения линий преобразования.Вероятно, вы должны сначала проверить, является ли он переносимым для какао.

...