使用匹配Python的模板在一个文件夹中查找和组织图像

发布于 2025-01-26 05:05:40 字数 1932 浏览 4 评论 0原文

我正在制作一个NFT项目,我制作了40000张图像,所以我想根据某些图像中的某些对象在文件夹中对它们进行排序
我使用的模板图像要比要复制所有具有相同obejct模板的图像到新文件夹的图像 我找到了openCV模板匹配 这是图像的图像,我想将所有与模板图像匹配的红色帽子复制到新文件夹 这是我的图像

这是我的代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import os, errno



threshold = 0.8 #set threshold
resultsDirectory = 'results'
sourceDirectory = os.fsencode(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\rrr')
templateDirectory = os.fsencode(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\3.png')
detectedCount = 0


for file in os.listdir(sourceDirectory):
    filename = os.fsdecode(file)
    if filename.endswith(".jpg") or filename.endswith(".png"): 

        print (filename)

        img_rgb = cv2.imread(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\rrr'+filename)
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

        for templateFile in os.listdir(templateDirectory):
            templateFilename = os.fsdecode(templateFile)

            if filename.endswith(".jpg") or filename.endswith(".png"):
                template = cv2.imread(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\3.png'+templateFilename,0)
                w, h = template.shape[::-1]
                res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
                loc = np.where( res >= threshold)

                if (len(loc[0])):
                    detectedCount = detectedCount + 1
                    for pt in zip(*loc[::-1]):
                        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
                    cv2.imwrite(resultsDirectory+'/res_'+filename+'.png',img_rgb)
                    print ('/res_'+filename+'.png'+' saved')
                    # break

        print ('detected positive ' + str(detectedCount))
        continue
    else:
        continue

i'm making an nft project i made 40000 images so i want to sort them in folders according to certain objects in certain image
i'm using template image than i want to copy all images that have the same obejct of the template to a new folder
i found opencv template matching
here is exmaples of images, i want to copy all images with red hat that match with template image to a new folder
here is my image

here is my code:

import cv2
import numpy as np
from matplotlib import pyplot as plt
from PIL import Image
import os, errno



threshold = 0.8 #set threshold
resultsDirectory = 'results'
sourceDirectory = os.fsencode(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\rrr')
templateDirectory = os.fsencode(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\3.png')
detectedCount = 0


for file in os.listdir(sourceDirectory):
    filename = os.fsdecode(file)
    if filename.endswith(".jpg") or filename.endswith(".png"): 

        print (filename)

        img_rgb = cv2.imread(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\rrr'+filename)
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)

        for templateFile in os.listdir(templateDirectory):
            templateFilename = os.fsdecode(templateFile)

            if filename.endswith(".jpg") or filename.endswith(".png"):
                template = cv2.imread(r'C:\Users\Amir\Desktop\Nouveau dossier (2)\3.png'+templateFilename,0)
                w, h = template.shape[::-1]
                res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
                loc = np.where( res >= threshold)

                if (len(loc[0])):
                    detectedCount = detectedCount + 1
                    for pt in zip(*loc[::-1]):
                        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
                    cv2.imwrite(resultsDirectory+'/res_'+filename+'.png',img_rgb)
                    print ('/res_'+filename+'.png'+' saved')
                    # break

        print ('detected positive ' + str(detectedCount))
        continue
    else:
        continue

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情归归情 2025-02-02 05:05:40

您想要的是一种足够快的提名交叉相关算法,我刚刚使用OpenCV实施了它。 github link

尽管C ++实现了它,但所有您都可以在Python版本中找到所有相应的OpenCV函数。

效果:

您可以使用函数匹配()在检查图像中查找对象,并获取旋转角度和像素位置。然后,您可以使用像素位置对所有图像进行排序。

整个版本太长了,无法在此处发布,请检查我的github。

代码的一部分如下:

int iSize = (int)vecAngles.size ();
vector<s_MatchParameter> vecMatchParameter (iSize * (m_iMaxPos + MATCH_CANDIDATE_NUM));

for (int i = 0; i < iSize; i++)
{
    Mat matRotatedSrc, matR = getRotationMatrix2D (ptCenter, vecAngles[i], 1);
    Mat matResult;
    Point ptMaxLoc;
    double dValue, dMaxVal;
    double dRotate = clock ();
    Size sizeBest = GetBestRotationSize (vecMatSrcPyr[iTopLayer].size (), pTemplData->vecPyramid[iTopLayer].size (), vecAngles[i]);
    float fTranslationX = (sizeBest.width - 1) / 2.0f - ptCenter.x;
    float fTranslationY = (sizeBest.height - 1) / 2.0f - ptCenter.y;
    matR.at<double> (0, 2) += fTranslationX;
    matR.at<double> (1, 2) += fTranslationY;
    warpAffine (vecMatSrcPyr[iTopLayer], matRotatedSrc, matR, sizeBest);


    MatchTemplate (matRotatedSrc, pTemplData, matResult, iTopLayer);

    minMaxLoc (matResult, 0, &dMaxVal, 0, &ptMaxLoc);

    vecMatchParameter[i * (m_iMaxPos + MATCH_CANDIDATE_NUM)] = s_MatchParameter (Point2f (ptMaxLoc.x - fTranslationX, ptMaxLoc.y - fTranslationY), dMaxVal, vecAngles[i]);

    for (int j = 0; j < m_iMaxPos + MATCH_CANDIDATE_NUM - 1; j++)
    {
        ptMaxLoc = GetNextMaxLoc (matResult, ptMaxLoc, -1, pTemplData->vecPyramid[iTopLayer].cols, pTemplData->vecPyramid[iTopLayer].rows, dValue, m_dMaxOverlap);
        vecMatchParameter[i * (m_iMaxPos + MATCH_CANDIDATE_NUM) + j + 1] = s_MatchParameter (Point2f (ptMaxLoc.x - fTranslationX, ptMaxLoc.y - fTranslationY), dValue, vecAngles[i]);
    }
}
FilterWithScore (&vecMatchParameter, m_dScore-0.05*iTopLayer);

What you want is a fast enough algorithm of nomalized cross correlation, and I just implemented it using OpenCV. github link

Although it is implemented by c++, all you can find all corresponded opencv functions in python version.

Effects:
enter image description here

You can use the function Match () to find objects in inspection images, and get the rotation angle and pixel position. You then can use the pixel position to sort all images.

The whole version is too long to be posted here, please check on my github.

Part of the code is as followed:

int iSize = (int)vecAngles.size ();
vector<s_MatchParameter> vecMatchParameter (iSize * (m_iMaxPos + MATCH_CANDIDATE_NUM));

for (int i = 0; i < iSize; i++)
{
    Mat matRotatedSrc, matR = getRotationMatrix2D (ptCenter, vecAngles[i], 1);
    Mat matResult;
    Point ptMaxLoc;
    double dValue, dMaxVal;
    double dRotate = clock ();
    Size sizeBest = GetBestRotationSize (vecMatSrcPyr[iTopLayer].size (), pTemplData->vecPyramid[iTopLayer].size (), vecAngles[i]);
    float fTranslationX = (sizeBest.width - 1) / 2.0f - ptCenter.x;
    float fTranslationY = (sizeBest.height - 1) / 2.0f - ptCenter.y;
    matR.at<double> (0, 2) += fTranslationX;
    matR.at<double> (1, 2) += fTranslationY;
    warpAffine (vecMatSrcPyr[iTopLayer], matRotatedSrc, matR, sizeBest);


    MatchTemplate (matRotatedSrc, pTemplData, matResult, iTopLayer);

    minMaxLoc (matResult, 0, &dMaxVal, 0, &ptMaxLoc);

    vecMatchParameter[i * (m_iMaxPos + MATCH_CANDIDATE_NUM)] = s_MatchParameter (Point2f (ptMaxLoc.x - fTranslationX, ptMaxLoc.y - fTranslationY), dMaxVal, vecAngles[i]);

    for (int j = 0; j < m_iMaxPos + MATCH_CANDIDATE_NUM - 1; j++)
    {
        ptMaxLoc = GetNextMaxLoc (matResult, ptMaxLoc, -1, pTemplData->vecPyramid[iTopLayer].cols, pTemplData->vecPyramid[iTopLayer].rows, dValue, m_dMaxOverlap);
        vecMatchParameter[i * (m_iMaxPos + MATCH_CANDIDATE_NUM) + j + 1] = s_MatchParameter (Point2f (ptMaxLoc.x - fTranslationX, ptMaxLoc.y - fTranslationY), dValue, vecAngles[i]);
    }
}
FilterWithScore (&vecMatchParameter, m_dScore-0.05*iTopLayer);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文