Napisałem kod do wykrywania twarzy na obrazach gazet. Próbuję powtórzyć listę tych znalezionych twarzy, skopiować je z obrazu i wkleić do nowego obrazu.

Nowy obraz miałby nazwę pliku u góry, a następnie mozaikę twarzy. Poniższy fragment kodu jest w rzeczywistości zapętlony przez kilka obrazów. Chcę, aby wszystkie nowe obrazy mozaiki skończyły się jako jeden duży obraz.

Oto mój kod:

pil_img = Image.open(imgfile)
opencvImage = cv.cvtColor(np.array(pil_img), cv.COLOR_RGB2BGR)
gray = cv.cvtColor(opencvImage, cv.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(opencvImage, scaleFactor=1.4, minNeighbors=4, minSize=(30,30))
my_faces = []
for x,y,w,h in faces:
    drawing.rectangle((x,y,x+w,y+h), outline="white")
my_faces.append((x,x+w,y,y+h))
for face in my_faces:
            print(face)
                # roi = i[face[0]:face[1], face[2]:face[3]]
                # cv.imshow('ROI',face)
                # cv.waitKey(0)
            contact_sheet=Image.new('RGB', (600,300))
            contact_sheet.show()
            pil_img.show()

Linie zakomentowane, gdy są aktywne, za pomocą następującego komunikatu o błędzie:

TypeError: 'Image' object is not subscriptable

To, co naprawdę chcę zrobić, to wkleić te twarze do nowego arkusza kontaktowego.

Dziękuję za pomoc!

0
Python_Learner_DK 20 grudzień 2019, 04:16
Co to jest komentowana zmienna "i", również przy dostępie do tablicy obrazów pierwszy indeks odpowiada y, a nie x. Możesz zrobić coś takiego --> roi = opencvImage[face[2]:face[3], face[0]:face[1]], cv.imshow("ROI", roi), cv.waitKey(0) .
 – 
unlut
20 grudzień 2019, 04:25
@unlut, komentowana zmienna i jest wersją PIL tego samego obrazu, użyłem jej, aby wykorzystać pytesseract, aby uzyskać tekst. Właściwie próbuję pobrać twarze z oryginalnego obrazu, a następnie wkleić je do nowego obrazu contact_sheet
 – 
Python_Learner_DK
20 grudzień 2019, 11:30

1 odpowiedź

Możesz zapisać je w swojej pętli for

index = 0
for x,y,w,h in faces:
    cv.imwrite(f'face_{index}.jpg', opencvImage[y:(y+h), x:(x+w), :])
    index += 1

Aby utworzyć montaż z oddzielnych obrazów, możesz użyć feh, jeśli masz go zainstalowanego:

feh -m -O montage.png *.jpg

Możesz także stworzyć montaż w czystym opencv, w tym celu zalecam najpierw zmianę rozmiaru twarzy do jednolitego rozmiaru, a następnie utworzenie ich połączenia:

face_imgs = []
for x,y,w,h in faces:
    face = opencvImage[y:(y+h), x:(x+w), :]
    thumbnail = cv2.resize(face, (100, 100))
    face_imgs.append(thumbnail)
faces = np.concatenate(face_imgs, axis=0)
1
shortcipher3 20 grudzień 2019, 23:18
Jeśli poprawnie czytam twój kod, utworzy to wiele obrazów .jpg dla każdej twarzy - to z pewnością połowa sukcesu - wypróbowałem kod w takim stanie, w jakim jest i otrzymałem NameError: name 'index' is not defined, więc próbowałem go zmienić na 'face_{}.jpg'.format(index) i otrzymał zmienną NameError: 'index' is not defined' even though I have the index` zdefiniowaną nad pętlą. Jakieś pomysły?
 – 
Python_Learner_DK
20 grudzień 2019, 11:25
Czy możesz wyjaśnić swoje wymagania? Chcesz wkleić wszystkie twarze do jednego nowego obrazu. Czy nowy obraz powinien mieć taki sam rozmiar jak oryginał, czy chcesz mozaiki twarzy, która stara się zmniejszyć odstępy?
 – 
shortcipher3
20 grudzień 2019, 16:50
Dodałem drugi akapit w pytaniu, aby odpowiedzieć, że wymaganie to nowy obraz mozaikowy, który zmniejsza odstępy. Dziękuję za pomoc w zadawaniu lepszych pytań!
 – 
Python_Learner_DK
20 grudzień 2019, 19:02
Udało mi się uzyskać twoją pierwszą odpowiedź - tworzenie obrazów, dziękuję. Nadal pracujemy nad połączeniem ich wszystkich. Oto nieco zmodyfikowany kod: ` dla x,y,w,h w twarzach: found_face_file_name = 'face_{}_{}_.jpg'.format(prefix,index) cv.imwrite(found_face_file_name, opencvImage[y:(y) +h), x:(x+w), :]) indeks += 1`
 – 
Python_Learner_DK
20 grudzień 2019, 20:51