문제

를 개발하고 그래픽을 사용하여 응용 프로그램 Qt4.5 와 두고 이미지에 QPixmapCache 고 싶었을 최적화하도록 이면 사용자가 삽입하는 이미지가 캐시에 그것을 사용하는 것입니다.

지금 각 이미지의 고유한 식별자를 가지고 있는 데 도움을 최적화 그 자체에 페인트는 이벤트입니다.그러나 내가 깨닫는다면 내가 계산할 수 있습 해시의 이미지가할 수 있 조회 캐시오 이미 존재하는 경우와 사용하는(그것이 도움이 될 것이 더 중복된 개체는 물론).

나의 문제는 경우는 그것의 큰 QPixmap 이 해시의 계산은 그것들이 빠른 방법이 있을까?

도움이 되었습니까?

해결책

몇의 의견이:

  1. 려고하는 경우에 당신을 생성하고 해시/캐시 키의 픽스맵할 수 있습니다 원하는 건너뛰 QPixmapCache 고 사용 QCache 직접.이거 약간의 오버헤드를 사용하 QStrings 로 키(지 않는 한 당신은 또한 당신을 사용하려는 파일의 경로를 찾을 수 항목)

  2. 로 Qt4.4,QPixmap 는"hash"값 그와 관련된(참조하십시오 QPixmap::cacheKey() ).문서 청구"뚜렷한 QPixmap 개체만 가질 수 있습 같은 캐시 키는 경우에는 동일한 내용입니다." 그러나,이후 Qt 사용유로 데이터를 복사할 수 있습만 적용을 복사 픽스맵과하지 않는 두 개의 픽스맵드에서 같은 이미지입니다.의 비트 테스트는 당신을 말할 것 그것이 작동하는 경우,그리고 만약 그렇다면,그것은 당신이 쉽게 얻을 해쉬값이다.

  3. 당신이 정말 하고 싶은 좋은,상당히 빠른 캐시 제거와 중복, 당신은 수도에서 보고 싶은 당신의 자신의 데이터 구조 는 종류에 따라 크기,색상을 깊이 이미지 유형,그와 같은 것들니다.당신은 것만 해시 실제 이미지 데이터는 당신이 발견 한 후에는 동일한 유형의 이미지와 동일한 크기를 조금 깊이,등등.의 경우 물론,사용자가 일반적으로 많이 열어 이미지의 그 것에 동일한,그것은 돕지 않다.

  4. 성능:에 대해 잊지 마세요 벤치마킹 재료 Qt 에 추가 4.5 는 비교하자 다양한 아이디어를 해싱하는 하나의 참조 실행됩니다.나는 확인하지 않은 그것을 밖으로 아직,그러나 그것은 꽤 깔끔합니다.

다른 팁

누군가 가이 문제를 발견 한 경우 (그리고 특히 이미지와 같은 해싱 물건에 대해 너무 많은 경험이없는 경우), 여기에 qpixmaps를 해싱하고 나중에 비교하기 위해 조회 테이블에 들어가는 데 사용한 매우 간단한 솔루션이 있습니다.

qint32 HashClass::hashPixmap(QPixmap pix)
{
    QImage image = pix.toImage();
    qint32 hash = 0;

    for(int y = 0; y < image.height(); y++)
    {
        for(int x = 0; x < image.width(); x++)
        {
            QRgb pixel = image.pixel(x,y);

            hash += pixel;
            hash += (hash << 10);
            hash ^= (hash >> 6);
        }
    }

    return hash;
}

해싱 함수 자체는 다음과 같습니다 (충돌이 적은 경우 Qint64로 해시 할 수 있습니다). 보시다시피 PixMap을 QIMAGE로 변환하고 차원을 걸어 가서 각 픽셀에서 한 번에 한 시간에 한 번에 한 번의 해외를 수행하고 최종 결과를 반환합니다. 이 구현을 개선하는 방법에는 여러 가지가 있지만 (이 질문에 대한 다른 답변 참조) 이것이해야 할 일의 기본 요점입니다.

OP는이 해싱 기능을 사용하여 나중에 이미지를 비교하기 위해 조회 테이블을 구성하는 방법을 언급했습니다. 매우 간단한 조회 초기화 기능이 필요합니다.

void HashClass::initializeImageLookupTable()
{
    imageTable.insert(hashPixmap(QPixmap(":/Image_Path1.png")), "ImageKey1");
    imageTable.insert(hashPixmap(QPixmap(":/Image_Path2.png")), "ImageKey2");
    imageTable.insert(hashPixmap(QPixmap(":/Image_Path3.png")), "ImageKey2");
// Etc...
}

나는 여기에서 QMAP를 사용하고 있는데, 이는 수업에서 다음과 같이 선언해야합니다.

QMap<qint32, QString> imageTable;

마지막으로, 이미지를 조회 테이블의 이미지와 비교하려면 (예 : "내가 알고있는 이미지에서 어떤 이미지 가이 특정 이미지입니까?") 해싱 함수를 호출합니다. 이미지 (QPIXMAP라고 가정)와 반환 QSTRING 값을 사용하면이를 알아낼 수 있습니다. 이와 같은 것이 효과가 있습니다.

void HashClass::compareImage(const QPixmap& pixmap)
{
    QString value = imageTable[hashPixmap(pixmap)];
    // Do whatever needs to be done with the QString value and pixmap after this point.
}

그게 다야. 나는 이것이 누군가를 도울 수 있기를 바랍니다. 나는 그것을 알아내는 경험을 기쁘게 생각했지만 시간을 절약했을 것입니다.

해시 계산은 사용하는 알고리즘에 따라 (디스크 I/O가 관련이없는 경우 100MB/s 이상) 매우 빠릅니다. 해싱 전에 잠재적 후보를 분류하기 위해 몇 가지 빠른 테스트를 수행 할 수도 있습니다.

물론 삽입 된 이미지의 해시 값을 유지해야하므로 새 이미지의 해시 만 계산하면 캐시 된 이미지에 대해 다시 계산할 필요가 없습니다.

이미지가 충분히 다르면 전체 이미지를 해시하지 않고 작은 썸네일이나 이미지의 일부 (Fe First 및 Last 10 라인)를 해시하는 것으로 충분할 것입니다. 이는 더 빠르지 만 더 많은 충돌로 이어질 것입니다.

QT가 생성 한 고유 한 ID를 얻는 대신 이미지 데이터보다 해시를 실제로 계산하는 것에 대해 이야기하고 있다고 가정합니다.
이미지에 따라 해시를 계산하기 위해 전체 이미지를 살펴볼 필요가 없습니다. 아마도 처음 10 픽셀 만 읽을 수 있습니까? 첫 번째 스캔 라인?
아마도 전체 이미지에서 의사의 랜덤 픽셀을 선택했을까요? (시퀀스를 반복 할 수 있도록 알려진 씨앗의 경우) 이미지의 크기를 해시에 추가하는 것을 잊지 마십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top