'finding and organizing images in one folder using template matching python
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
Solution 1:[1]
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.
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);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

