चेहरे की पहचान


43

इस कार्य का उद्देश्य किसी भी 'छवि' में सभी चेहरों की पहचान करना, उन्हें साफ करना और चिन्हित करना है।

चेहरे में क्या है?

एक चेहरा एक ZxZ वर्ग होगा जहाँ Z 1 से अधिक एक विषम पूर्णांक है। शीर्ष बाएँ और दाएँ कोने और केंद्र 'O' वर्ण होंगे, और निचला रेखा एक '\' और 'a' पर्याप्त रूप से चारों ओर होगा। '_' अक्षर शेष रेखा को भरने के लिए। उदाहरण:

एक 3x3 चेहरा:

O O
 O
\_/

5x5 का चेहरा:

O   O

  O

\___/

एक 7x7 चेहरा:

O     O


   O


\_____/

आदि।

इनपुट

इनपुट STDIN पर होगा और इसमें पात्रों की समान लंबाई के कई तार शामिल होंगे।

उत्पादन

आउटपुट सभी पहचाने जाने योग्य चेहरों के साथ इनपुट होना चाहिए (यानी आंखों, नाक और मुंह के अलावा सभी पात्रों को चेहरे की सीमा के भीतर से हटा दिया जाना चाहिए) और बॉक्सिंग (चारों ओर से घिरा हुआ, +, - और वर्ण)। जहां दो या अधिक चेहरे ओवरलैप करते हैं, दोनों को साफ किया जाना चाहिए और बॉक्सिंग किया जाना चाहिए, लेकिन प्राथमिकता बड़े चेहरे को दी जानी चाहिए (इसे शीर्ष पर रखा जाना चाहिए); यदि दोनों चेहरे समान आकार के हैं, तो प्राथमिकता कार्यान्वयनकर्ता के विवेक पर छोड़ दी जाती है। यदि इनपुट में कोई चेहरा नहीं है, तो आउटपुट इनपुट के समान होना चाहिए।

कुछ उदाहरण

इनपुट:

*******
*******
**O*O**
***O***
**\_/**
*******
*******

आउटपुट:

*******
*+---+*
*|O O|*
*| O |*
*|\_/|*
*+---+*
*******

इनपुट (अधूरा चेहरा):

*******
*******
**O*O**
*******
**\_/**
*******
*******

आउटपुट:

*******
*******
**O*O**
*******
**\_/**
*******
*******

इनपुट (नेस्टेड चेहरे):

*******
*O***O*
**O*O**
***O***
**\_/**
*\___/*
*******

आउटपुट:

+-----+
|O   O|
|     |
|  O  |
|     |
|\___/|
+-----+

इनपुट (कई चेहरे):

~{$FJ*TBNFU*YBVEXGY%
FOCO$&N|>ZX}X_PZ<>}+
X$OOPN ^%£)LBU{JJKY%
@\_/$£!SXJ*)KM>>?VKH
SDY%£ILO(+{O:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJO$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@\___/GER%^*BI
@{PO{_):<>KNUYT*&G&^

आउटपुट:

+---+*TBNFU*YBVEXGY%
|O O|&N|>ZX}X_PZ<>}+
| O |N ^%£)LBU{JJKY%
|\_/|£+-----+M>>?VKH
+---+I|O   O|HO(UR$W
XVBFTE|     |LO*(&P:
>?LKPO|  O  |&L:}~{&
~@?}{)|     |@~}P>OU
:@<L::|\___/|ER%^*BI
@{PO{_+-----+YT*&G&^

इनपुट (सीमा के पास):

~{$FJ*TBNFU*YBVEXGY%
OCO$&N|>ZX}X_PZ<>}+^
$OOPN ^%£)LBU{JJKY%{
\_/$£!SXJ*)KM>>?VKHU
SDY%£ILO(+{8:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJ^$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@BJYT*GER%^*BI
@{PO{_):<>KNUYT*&G&^

आउटपुट:

---+J*TBNFU*YBVEXGY%
O O|&N|>ZX}X_PZ<>}+^
 O |N ^%£)LBU{JJKY%{
\_/|£!SXJ*)KM>>?VKHU
---+£ILO(+{8:HO(UR$W
XVBFTER^&INLNLO*(&P:
>?LKPO)UJ^$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@BJYT*GER%^*BI
@{PO{_):<>KNUYT*&G&^

इनपुट (चेहरे को ओवरलैप करते हुए):

~{$FJ*TBNFU*YBVEXGY%
FXC£$&N|>ZX}X_PZ<>}+
X$*OPN O%£)LBO{JJKY%
@:U%$£!SXJ*)KM>>?VKH
SDY%£OLO(+{P:HO(UR$W
XVBFTER^&IOLNLO*(&P:
>?L\___/JR$£^&L:}~{&
~@?}{)JKOINLM@~}P>OU
:@<L::@\_____/R%^*BI
@{PO{_):<>KNUYT*&G&^

आउटपुट:

~{$FJ*TBNFU*YBVEXGY%
FX+---+-------+Z<>}+
X$|O  |O     O|JJKY%
@:|   |       |>?VKH
SD|  O|       |(UR$W
XV|   |   O   |*(&P:
>?|\__|       |:}~{&
~@+---|       |}P>OU
:@<L::|\_____/|%^*BI
@{PO{_+-------+*&G&^

संयुग्मित चेहरों के बारे में क्या है (उदाहरण के लिए जहां एक O बाईं आंख और दाईं आंख के रूप में दोहराता है)? क्या उन्हें ओवरलैपिंग माना जाना चाहिए?
जॉय एडम्स

@ जोए एडम्स: जो अंतिम उदाहरण में होता है।
लोजैकर

@Joey Adams @Lowjacker हां, पिछले उदाहरण की तरह।
गारेथ

मुझे 3x3 चेहरा यथार्थवादी और 7x7 चेहरा derp लगता है। एकदम मेरे विचार। दुख की बात है कि मुझे बाउंटी हासिल करने का समय नहीं मिला ... :)
21

2
@tomsmeding यदि आपको 3x3 का चेहरा वास्तविक लगता है तो मैं उन लोगों को देखना पसंद करूँगा जिनसे आप संबद्ध हैं। : - \
गैरेथ

जवाबों:


19

रूबी, 304 298 295 वर्ण

I=$<.read
q=(O=I*s=1).size
k=??+O=~/$/
o=->m,n{n.chars{|c|(m+=1)*(m%k)>0&&m<q&&O[m-1]=c}}
q.times{f=[[?\\+?_*s+?/,k*s+=1],[?O,0],[?O,s],[?O,(s+=1)/2*(1+k)]]
q.times{|x|f.all?{|a,b|I[x+b,a.size]==a}&&(o[x+k*s-1,o[x-k-1,?++?-*s+?+]]
s.times{|a|o[x+k*a-1,?|+' '*s+?|]}
f.map{|a,b|o[x+b,a]})}}
$><<O

यदि दाएं समान आकार के हों, तो ओवरलैप पर निचले दाएं को प्राथमिकता दी जाती है। जैसे इनपुट के लिए

O.OO.O
.O..O.
\_/\_/
O.OO.O
.O..O.
\_/\_/

यह सभी चार चेहरों और पैदावार को पहचानता है

O |O O
 O| O
--+---
O |O O
 O| O
\_|\_/

संपादित 1: लॉजैकर के रूप में प्रस्तावित हम indexएक रेगेक्स मैच (-3 वर्ण) के साथ बदल सकते हैं । इसके अलावा +1मिलान से पहले एक अतिरिक्त डमी चार द्वारा क्षतिपूर्ति की जा सकती है जो एक और चार्ट बचाता है ( +1डमी चार के लिए +3 के लिए -2, क्योंकि कोष्ठक अधिक आवश्यक नहीं हैं)। दो और चूंकि हम सीमा को बिना कोष्ठक के भी लिख सकते हैं।

संपादित करें 2: एक और दो वर्णों को दोनों के ifसाथ बदलकर बचाया जाता है &&और दूसरा एक पूरी तरह से सीमा को हटा देता है।


आप तीसरी पंक्ति (3 वर्णों को बचाता है) के (O=~/$/)बजाय उपयोग कर सकते हैं O.index($/)
लोजैकर जू

@Lowjacker धन्यवाद। मैं आपकी चाल के साथ एक और भी बचा सकता था (मेरा संपादन देखें)।
हावर्ड

मुझे लगता है कि आप ifबयानों को बदलकर 2 पात्रों को भी बचा सकते हैं &&
लोएजैकर

4

अजगर - 1199 941

मुझे समस्या काफी दिलचस्प लगी, इसलिए मैंने पायथन में हल किया। यहाँ संपीड़ित कोड है।

#!/usr/bin/env python
import fileinput,sys
m=[[c for c in l if c!='\n'] for l in fileinput.input()]
X=len(m[0])
Y=len(m)
t=[]
for n in range(3,min(X,Y)+1,2):
  for x in range(X-n+1):
    for y in range(Y-n+1):
      if m[y][x]=='O' and m[y][x+n-1]=='O' and m[y+(n//2)][x+(n//2)]=='O' and m[y+n-1][x]=='\\' and m[y+n-1][x+n-1]=='/' and "".join(m[y+n-1][x+1:x+n-1])=='_'*(n-2):
        t.append((x,y,n))
for x,y,n in t:
  def a(v,h,c):
    w=x+h; z=y+v;
    if z>=0 and z<len(m):
      if w>=0 and w<len(m[y]):
        m[z][w]=c
  for v in range(n):
    for h in range(n): 
      a(v,h,' ')
  a(0,0,'O')
  a(0,n-1,'O')
  a(n/2,n/2,'O')
  a(n-1,0,'\\')
  a(n-1,n-1,'/')
  for w in range(1,n-1):
    a(n-1,w,'_')
  for v in [-1,n]:
    for h in range(n):
      a(v,h,'-')
  for h in [-1,n]:
    for v in range(n):
      a(v,h,'|')
  a(-1,-1,'+')
  a(-1,n,'+')
  a(n,-1,'+')
  a(n,n,'+')
for l in m:
  for c in l:
    sys.stdout.write(c)
  print

यहाँ अधिक पठनीय कोड है:

#!/usr/bin/env python

import fileinput, sys

matrix = [[c for c in l if c != '\n'] for l in fileinput.input()]

max_X = len(matrix[0])
max_Y = len(matrix)

tuples = []
for n in range(3, min(max_X, max_Y)+1, 2):
  for x in range(max_X-n+1):
    for y in range(max_Y-n+1):
      # if is_face(matrix, x, y, n):
      if matrix[y][x] == 'O' and matrix[y][x+n-1] == 'O' and matrix[y+(n//2)][x+(n//2)] == 'O' and matrix[y+n-1][x] == '\\' and matrix[y+n-1][x+n-1] == '/' and "".join(matrix[y+n-1][x+1:x+n-1]) == '_'*(n-2) :
        tuples.append((x, y, n))

for x,y,n in tuples:
  # blank_and_border(matrix,x,y,n)
  def assign(dy, dx, c):
    xx = x + dx; yy = y + dy;
    if yy >= 0 and yy < len(matrix) :
      if xx >= 0 and xx < len(matrix[y]) :
        matrix[yy][xx] = c

  # blank
  for dy in range(n):
    for dx in range(n): 
      assign(dy, dx, ' ')

  # face
  assign(0, 0, 'O')
  assign(0, n-1, 'O')
  assign(n/2, n/2, 'O')
  assign(n-1, 0, '\\')
  assign(n-1, n-1, '/')
  for w in range(1,n-1):
    assign(n-1, w, '_')

  # border
  for dy in [-1,n]:
    for dx in range(n):
      assign(dy, dx, '-')

  for dx in [-1,n]:
    for dy in range(n):
      assign(dy, dx, '|')

  assign(-1, -1, '+')
  assign(-1,  n, '+')
  assign( n, -1, '+')
  assign( n,  n, '+')

for l in matrix:
  for c in l:
    sys.stdout.write(c)
  print

2
कृपया अपने उत्तर में अपने गोल्फ संस्करण को इस संस्करण के ऊपर जोड़ें। यह एक कोड-गोल्फ प्रश्न है और यदि आप कम से कम इसे गोल्फ के लिए प्रयास नहीं करते हैं तो आपको वोट कम होने का जोखिम है। आप यहां अपना पठनीय संस्करण भी छोड़ सकते हैं।
गारेथ

1
ठीक है, @ गैरेथ। मैं अक्सर जावा में समाधान लिखता हूं, जो बहुत गोल्फ के अनुकूल नहीं है, लेकिन मैं हमेशा अपने समाधान के लिए गोल्फ का समय निकालता हूं, दोनों अभ्यास के लिए (यह पात्रों को ट्रिम करने के तरीके और कुल लंबाई को कम करने के लिए मजेदार सोच है) और की भावना को संतुष्ट करने के लिए कोड-गोल्फ (जो आपके समाधान को यथासंभव संक्षिप्त रूप में प्राप्त कर रहा है)। तो, अपने गोल्फ समाधान, sgauria देखने के लिए आगे देख!
प्रोग्रामरडान

धन्यवाद गारेथ और @ProgrammerDan! यह अच्छी सलाह है - मैं कोडगुल्फ़ पर बहुत नया हूँ। मैंने अपने घोल के घोल को ऊपर के घोल के अतिरिक्त डाल दिया है।
सगौरिया
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.