def main2D_3D_2D_LowResolution(): '''1. read origin obj and image''' objPath = '../../github/vrn-07231340/obj/trump-12.obj' objLines, vLines, fLines = readObj(objPath) imgPath = '../../github/vrn-07231340/examples/scaled/trump-12.jpg' img = cv2.imread(imgPath) '''2. origin 2D landmark --> origin 3D landmark''' ''' BUT ONE 2D LANDMARK --> MORE THAN ONE 3D LANDMARK''' ''' HOW TO CHOOSE THE BEST ONE ?''' ''' OPTION 1: 选Z最大的3D landmark''' '''2.1 origin 2D landmark [x, y]''' originLandmark2DList = getLandmark2D(img) '''2.2 origin 3D landmark list [[[x, y], [(line1, vLine1), (line2, vLine2)]], ... ]''' originLandmark3DList = getLandmark3D(originLandmark2DList, vLines) '''2.3 OPTION 1: 选Z最大的3D landmark''' originLandmark3DList = optionChooseZMax(originLandmark3DList) '''3. nod''' nodAngle = 15 nodCenterMode = 'maxY' nodedObjLines = nod(objPath, nodAngle, nodCenterMode) '''4. noded 3D landmark list''' '''nodedLandmark3DList: [[x0, y0], [x0, y0, z0], [x1, y1], [x1, y1, z1], (line, vLine)]''' '''len(nodedLandmark3DList): number of landmarks both on 2D and 3D''' '''[x0, y0]: original landmark on 2D img''' '''[x0, y0, z0]: original landmark on 3D model''' '''[x1, y1]: noded landmark on 2D img''' '''[x1, y1, z1]: noded landmark on 3D model''' '''(line, vLine): the line(th) noded vLine''' nodedVLines = objLines2vLines(nodedObjLines) nodedLandmark3DList = getNodedLandmark3D(nodedVLines, originLandmark3DList) '''5. noded 3D landmark --> noded 2D landmark''' nodedLandmark2D = [] for nodedLandmark3D in nodedLandmark3DList: nodedLandmark2D.append(nodedLandmark3D[2]) nodedLandmark2D = addEdgeLandmark(nodedLandmark2D, img) '''6. delaunay triangle for (origin landmarks which are both on 2D and 3D) + (eight edge points)''' originLandmark2D = [] for nodedLandmark3D in nodedLandmark3DList: originLandmark2D.append((nodedLandmark3D[0][0], nodedLandmark3D[0][1])) originLandmark2D = addEdgeLandmark(originLandmark2D, img) assert len(originLandmark2D) == len(nodedLandmark2D) triList = generateTriList(originLandmark2D, img) '''7. warp''' imgMorph = morph_modify_for_2D3D2D_low_resolution(originLandmark2D, nodedLandmark2D, img, triList) imshow('imgMorph', imgMorph) cv2.imwrite('./noded.jpg', imgMorph)
def main2D_3D_2D_LR_Hair(): '''1. read origin obj and image''' objPath = '../../github/vrn-07231340/obj/trump-12.obj' objLines, vLines, fLines = readObj(objPath) imgPath = '../../github/vrn-07231340/examples/scaled/trump-12.jpg' img = cv2.imread(imgPath) imgHRPath = '../../github/vrn-07231340/examples/trump-12.jpg' imgHR = cv2.imread(imgHRPath) '''2. origin 2D landmark --> origin 3D landmark''' ''' BUT ONE 2D LANDMARK --> MORE THAN ONE 3D LANDMARK''' ''' HOW TO CHOOSE THE BEST ONE ?''' ''' OPTION 1: 选Z最大的3D landmark''' '''2.1 origin 2D landmark [x, y]''' originLandmark2DList = getLandmark2D(img) '''2.2 origin 3D landmark list [[[x, y], [(line1, vLine1), (line2, vLine2)]], ... ]''' originLandmark3DList = getLandmark3D(originLandmark2DList, vLines) '''2.3 OPTION 1: 选Z最大的3D landmark''' originLandmark3DList = optionChooseZMax(originLandmark3DList) '''3. nod''' nodAngle = 15 nodCenterMode = 'maxY' nodObjLines = nod(objPath, nodAngle, nodCenterMode) '''4. nod 3D landmark list''' '''nodLandmark3DList: [[x0, y0], [x0, y0, z0], [x1, y1], [x1, y1, z1], (line, vLine)]''' '''len(nodLandmark3DList): number of landmarks both on 2D and 3D''' '''[x0, y0]: original landmark on 2D img''' '''[x0, y0, z0]: original landmark on 3D model''' '''[x1, y1]: nod landmark on 2D img''' '''[x1, y1, z1]: nod landmark on 3D model''' '''(line, vLine): the line(th) nod vLine''' nodVLines = objLines2vLines(nodObjLines) nodLandmark3DList = getNodLandmark3D(nodVLines, originLandmark3DList) '''5. nod 3D landmark --> nod 2D landmark''' nodLandmark2D = [] for nodLandmark3D in nodLandmark3DList: nodLandmark2D.append(nodLandmark3D[2]) '''6. origin 2D landmarks''' originLandmark2D = [] for nodLandmark3D in nodLandmark3DList: originLandmark2D.append((nodLandmark3D[0][0], nodLandmark3D[0][1])) assert len(originLandmark2D) == len(nodLandmark2D) '''7. face 2D landmarks + hair 2D landmarks''' # hairLandmark2DList, nodHairLandmark2DList = main2D_3D_2D_ManuallySelectHair() hairLandmark2DList, nodHairLandmark2DList, edgePoints, ellipseVerts, outerEllipseVerts = main2D_3D_2D_LR_MeshHair( ) assert len(hairLandmark2DList) == len(nodHairLandmark2DList) '''7.1 origin face 2D landmarks + origin hair 2D landmarks''' originLandmark2D = originLandmark2D + hairLandmark2DList '''7.2 nod face 2D landmarks + nod hair 2D landmarks''' nodLandmark2D = nodLandmark2D + nodHairLandmark2DList '''7.3 save origin and nod 2D landmarks txt''' # originLandmark2DTxtPath = './originLandmark2D.txt' # originLandmark2DTxt = open(originLandmark2DTxtPath, 'w') # for i in originLandmark2D: # originLandmark2DTxt.write('{} {}\n'.format(i[0], i[1])) # originLandmark2DTxt.close() # nodLandmark2DTxtPath = './nodLandmark2D.txt' # nodLandmark2DTxt = open(nodLandmark2DTxtPath, 'w') # for i in nodLandmark2D: # nodLandmark2DTxt.write('{} {}\n'.format(i[0], i[1])) # nodLandmark2DTxt.close() '''8. add edge points''' '''8.1 OPTION1: 8 IMAGE EDGE POINTS''' ''' 如果在加头发关键点之前加8个edge points,第7个edge point(图像最上面那个)会被往下warp一点''' ''' 如果在加头发关键点之后加8个edge points,第7个edge point经过warp后仍在原处,形成一个小三角''' # originLandmark2D = addEdgeLandmark(originLandmark2D, img) # nodLandmark2D = addEdgeLandmark(nodLandmark2D, img) '''8.2 OPTION2: OUTER ELLIPSE''' # a = copy.copy(originLandmark2D) originLandmark2D = originLandmark2D + edgePoints nodLandmark2D = nodLandmark2D + edgePoints # drawPointsOnImg(originLandmark2D, img, 'b') # drawPointsOnImg(a, img, 'r') # drawPointsOnImg(nodLandmark2D, img, 'g') # drawPointsOnImg(ellipseVerts, img, 'g', cover=True) # drawPointsOnImg(outerEllipseVerts, img, 'r', cover=True) # drawPointsOnImg(originLandmark2D, img, 'g', cover=True) # drawPointsOnImg(edgePoints, img, 'b', radius=3) # drawPointsOnImg(nodLandmark2D, img, 'r') '''9. delaunay triangle for [origin landmarks (face + hair)] + (eight edge points)''' # triList = generateTriList(originLandmark2D, img) # '''9.1 save tri txt''' # triTxtPath = './nodTri.txt' # triTxt = open(triTxtPath, 'w') # for i in triList: # triTxt.write('{}\n'.format(i)) # triTxt.close() '''10. warp LR''' # imgMorph = morph_modify_for_2D3D2D_low_resolution( # originLandmark2D, nodLandmark2D, img, triList) # imshow('imgMorph', imgMorph) # cv2.imwrite('./nod.jpg', imgMorph) # return originLandmark2D, nodLandmark2D, triList '''LR to HR''' originLandmark2DHR = LR2HR(img, imgHR, originLandmark2D) for (x, y), (xmin, ymin) in zip(originLandmark2DHR, originLandmark2D): if float(x) >= 640 or float(y) >= 640: print(int(xmin), int(ymin)) cv2.circle(img, (int(xmin), int(ymin)), 3, (0, 255, 0), -1) imshow('img', img) nodLandmark2DHR = LR2HR(img, imgHR, nodLandmark2D) '''8. add 8 egde points''' # nodLandmark2DHR = addEdgeLandmark(nodLandmark2DHR, imgHR) # originLandmark2DHR = addEdgeLandmark(originLandmark2DHR, imgHR) # drawPointsOnImg(originLandmark2DHR, imgHR, 'g') # drawPointsOnImg(nodLandmark2DHR, imgHR, 'r') '''8.1 remove >= 640''' originLandmark2DHR = [(i[0], i[1]) for i in originLandmark2DHR if i[0] < imgHR.shape[0] and i[1] < imgHR.shape[1]] nodLandmark2DHR = [(i[0], i[1]) for i in nodLandmark2DHR if i[0] < imgHR.shape[0] and i[1] < imgHR.shape[1]] '''9. delaunay triangle for [origin landmarks (face + hair)] + (edge points)''' triList = generateTriList(originLandmark2DHR, imgHR) '''9.1 save tri txt''' triTxtPath = './nodTri.txt' triTxt = open(triTxtPath, 'w') for i in triList: triTxt.write('{}\n'.format(i)) triTxt.close() '''10. warp HR''' imgMorph = morph_modify_for_2D3D2D_low_resolution(originLandmark2DHR, nodLandmark2DHR, imgHR, triList) # imshow('imgMorph', imgMorph) # cv2.imwrite('./nod.jpg', imgMorph) return originLandmark2DHR, nodLandmark2DHR, triList
def mainTurnHR(): '''1. read img LR and HR''' imgLRPath = '../../github/vrn-07231340/examples/scaled/trump_12.jpg' imgLR = cv2.imread(imgLRPath) imgHRPath = '../../github/vrn-07231340/examples/trump_12.png' imgHR = cv2.imread(imgHRPath) objPath = '../../github/vrn-07231340/obj/trump_12.obj' '''2. img LR --> HR''' zRatio = 3 objLinesHR, vLinesHR, landmarkLR, landmarkHR = lr2hr3DModel( imgLR, imgHR, zRatio, objPath) '''3. HR: origin 2D landmark --> origin 3D landmark''' originLandmark3DList = getLandmark3DHR(landmarkHR, vLinesHR) originLandmark3DList = optionChooseZMax(originLandmark3DList) faceLandmarkVlines = [] for (_, _, (_, vLine)) in originLandmark3DList: faceLandmarkVlines.append(vLine) '''4. HR: collar detection''' _, collarPoint = collarDetection(imgHR, minSize=1200, offset=15) '''5. HR: hair detection''' originHairPoints = hairDetection(imgHR, minSize=20000) '''5.1 hair points 不应该全部都在一个平面上(minZ=200),他们应该在一个曲面上''' ''' 取XZ平面上face landmark的三个极点,画一个圆''' ''' 除了face landmark以外的所有点 的 z,都落到圆上''' '''5.1.1 face landmark上XZ平面的三个极点''' faceLandmarkOnXZ = [] for faceLandmarkVline in faceLandmarkVlines: v, x, y, z, r, g, b = faceLandmarkVline.split() faceLandmarkOnXZ.append((float(x), float(z))) faceLandmarkOnXZMinX = min(faceLandmarkOnXZ, key=lambda x: x[0]) faceLandmarkOnXZMaxX = max(faceLandmarkOnXZ, key=lambda x: x[0]) faceLandmarkOnXZMaxZ = max(faceLandmarkOnXZ, key=lambda x: x[1]) '''5.1.2 三点构成一个圆''' circleCenterXOnXZ, circleCenterZOnXZ, radiusOnXZ = threePoints2Circle( faceLandmarkOnXZMinX, faceLandmarkOnXZMaxX, faceLandmarkOnXZMaxZ) circleCenterZOnXZ = circleCenterZOnXZ-70 '''5.1.3 把这个圆扩大,圆心不动,半径扩大至hair points的极点''' k1 = abs(circleCenterXOnXZ-max(originHairPoints, key=lambda x: x[0])[0]) k2 = abs(circleCenterXOnXZ-min(originHairPoints, key=lambda x: x[0])[0]) radiusOnXZ = max([k1, k2])+5 rr, cc = circle_perimeter(int(circleCenterXOnXZ), int( circleCenterZOnXZ), int(radiusOnXZ)) circleOnXZ = np.dstack([rr, cc])[0] '''5.1.4 hair points 的 z 落在圆上''' hairPointsVlines = [] for (x, y) in originHairPoints: maxZ = 0 for (x0, z0) in circleOnXZ: if int(x) == int(x0): if z0 > maxZ: maxZ = z0 hairVline = '{} {} {} {} {} {} {}'.format('v', x, y, maxZ, 0, 0, 0) hairPointsVlines.append(hairVline) maxZ = 0 assert len(hairPointsVlines) == len(originHairPoints) '''6. HR: face landmarks + hair points''' originVlines = faceLandmarkVlines+hairPointsVlines '''7. HR: turn face and hair''' turnAngle = 10 turnDirection = ['left', 'right'] turnCenterMode = 'maxY' leftTurnVLines = turnHR(originVlines, turnAngle, turnDirection[0], turnCenterMode) rightTurnVLines = turnHR(originVlines, turnAngle, turnDirection[1], turnCenterMode) assert len(originVlines) == len(leftTurnVLines) == len(rightTurnVLines) '''8. HR: turn 3D --> 2D''' originPointsHR = [] leftTurnPointsHR = [] rightTurnPointsHR = [] for originVline, leftTurnVLine, rightTurnVLine in zip(originVlines, leftTurnVLines, rightTurnVLines): _, x, y, _, _, _, _ = originVline.split() originPointsHR.append((float(x), float(y))) _, x, y, _, _, _, _ = leftTurnVLine.split() leftTurnPointsHR.append((float(x), float(y))) _, x, y, _, _, _, _ = rightTurnVLine.split() rightTurnPointsHR.append((float(x), float(y))) assert len(originPointsHR) == len( leftTurnPointsHR) == len(rightTurnPointsHR) # drawPointsOnImg(originPointsHR, imgHR, 'g') # drawPointsOnImg(turnPointsHR, imgHR, 'r') ''''9. inner ellipse''' left = min(originPointsHR, key=lambda x: x[0])[0] right = max(originPointsHR, key=lambda x: x[0])[0] up = min(originPointsHR, key=lambda x: x[1])[1] bottom = max(originPointsHR, key=lambda x: x[1])[1] innerEllipseCenterX = int((left+right)/2.0) innerEllipseCenterY = int((up+bottom)/2.0) innerEllipseSemiX = int((right-left)/2.0) innerEllipseSemiY = int((bottom-up)/2.0) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, innerEllipseSemiY, innerEllipseSemiX, orientation=np.pi*1.5) innerEllipseVerts = np.dstack([rr, cc])[0] '''10. outer ellipse''' '''10.1 ratio = outer ellipse / inner ellipse''' ''' 椭圆心和衣领的线段 和 椭圆的交点''' minDistance = np.inf for pt in innerEllipseVerts: distance = twoPointsDistance(pt, collarPoint) if distance < minDistance: minDistance = distance ratio = twoPointsDistance((innerEllipseCenterX, innerEllipseCenterY), collarPoint) / \ twoPointsDistance( (innerEllipseCenterX, innerEllipseCenterY), pt) '''10.2 outer ellipse''' outerEllipseSemiX = int(ratio*innerEllipseSemiX) outerEllipseSemiY = int(ratio*innerEllipseSemiY) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, outerEllipseSemiY, outerEllipseSemiX, orientation=np.pi*1.5) outerEllipseVerts = np.dstack([rr, cc])[0] # drawPointsOnImg(outerEllipseVerts, imgHR, 'g') '''11. edge points on outer ellipse''' edgePoints = edgePointsOnOuterEllipse(outerEllipseVerts) '''12. final origin and turn points''' originPointsHRFinal = originPointsHR+edgePoints leftTurnPointsHRFinal = leftTurnPointsHR+edgePoints rightTurnPointsHRFinal = rightTurnPointsHR+edgePoints '''13. tri.txt''' triList = generateTriList( originPointsHRFinal, imgHR, triTxtPath='./turnTri.txt') '''14. warp''' # imgMorph = morph_modify_for_2D3D2D_low_resolution( # originPointsHRFinal, turnPointsHRFinal, imgHR, triList) # imshow('imgMorph', imgMorph) # cv2.imwrite('./imgMorph.png', imgMorph) return originPointsHRFinal, leftTurnPointsHRFinal, rightTurnPointsHRFinal, triList
def main2D_3D_2D_LR_Hair(): '''1. read origin obj and image''' objPath = '../../github/vrn-07231340/obj/trump-12.obj' objLines, vLines, fLines = readObj(objPath) imgPath = '../../github/vrn-07231340/examples/scaled/trump-12.jpg' img = cv2.imread(imgPath) '''2. origin 2D landmark --> origin 3D landmark''' ''' BUT ONE 2D LANDMARK --> MORE THAN ONE 3D LANDMARK''' ''' HOW TO CHOOSE THE BEST ONE ?''' ''' OPTION 1: 选Z最大的3D landmark''' '''2.1 origin 2D landmark [x, y]''' originLandmark2DList = getLandmark2D(img) '''2.2 origin 3D landmark list [[[x, y], [(line1, vLine1), (line2, vLine2)]], ... ]''' originLandmark3DList = getLandmark3D(originLandmark2DList, vLines) '''2.3 OPTION 1: 选Z最大的3D landmark''' originLandmark3DList = optionChooseZMax(originLandmark3DList) '''3. nod''' nodAngle = 15 nodCenterMode = 'maxY' nodObjLines = nod(objPath, nodAngle, nodCenterMode) '''4. nod 3D landmark list''' '''nodLandmark3DList: [[x0, y0], [x0, y0, z0], [x1, y1], [x1, y1, z1], (line, vLine)]''' '''len(nodLandmark3DList): number of landmarks both on 2D and 3D''' '''[x0, y0]: original landmark on 2D img''' '''[x0, y0, z0]: original landmark on 3D model''' '''[x1, y1]: nod landmark on 2D img''' '''[x1, y1, z1]: nod landmark on 3D model''' '''(line, vLine): the line(th) nod vLine''' nodVLines = objLines2vLines(nodObjLines) nodLandmark3DList = getNodLandmark3D(nodVLines, originLandmark3DList) '''5. nod 3D landmark --> nod 2D landmark + 8 edge points''' nodLandmark2D = [] for nodLandmark3D in nodLandmark3DList: nodLandmark2D.append(nodLandmark3D[2]) nodLandmark2D = addEdgeLandmark(nodLandmark2D, img) '''6. origin 2D landmarks + 8 edge points''' originLandmark2D = [] for nodLandmark3D in nodLandmark3DList: originLandmark2D.append((nodLandmark3D[0][0], nodLandmark3D[0][1])) originLandmark2D = addEdgeLandmark(originLandmark2D, img) assert len(originLandmark2D) == len(nodLandmark2D) '''7. face 2D landmarks + hair 2D landmarks''' # hairLandmark2DList, nodHairLandmark2DList = main2D_3D_2D_ManuallySelectHair() hairLandmark2DList, nodHairLandmark2DList = main2D_3D_2D_LR_MeshHair() '''7.1 origin face 2D landmarks + origin hair 2D landmarks''' originLandmark2D = originLandmark2D+hairLandmark2DList # drawPointsOnImg(originLandmark2D, img, 'g') '''7.2 nod face 2D landmarks + nod hair 2D landmarks''' nodLandmark2D = nodLandmark2D+nodHairLandmark2DList # drawPointsOnImg(nodLandmark2D, img, 'r') '''7.3 save origin and nod 2D landmarks txt''' originLandmark2DTxtPath = './originLandmark2D.txt' originLandmark2DTxt = open(originLandmark2DTxtPath, 'w') for i in originLandmark2D: originLandmark2DTxt.write('{} {}\n'.format(i[0], i[1])) originLandmark2DTxt.close() nodLandmark2DTxtPath = './nodLandmark2D.txt' nodLandmark2DTxt = open(nodLandmark2DTxtPath, 'w') for i in nodLandmark2D: nodLandmark2DTxt.write('{} {}\n'.format(i[0], i[1])) nodLandmark2DTxt.close() '''8. delaunay triangle for [origin landmarks (face + hair)] + (eight edge points)''' triList = generateTriList(originLandmark2D, img) # print triList '''8.1 save tri txt''' triTxtPath = './nodTri.txt' triTxt = open(triTxtPath, 'w') for i in triList: triTxt.write('{}\n'.format(i)) triTxt.close() '''9. warp''' imgMorph = morph_modify_for_2D3D2D_low_resolution( originLandmark2D, nodLandmark2D, img, triList) # imshow('imgMorph', imgMorph) cv2.imwrite('./nod.jpg', imgMorph)
def mainTurnHRHairOnEllipsoid(): '''1. read img LR and HR''' imgLRPath = '../../github/vrn-07231340/examples/scaled/trump_12.jpg' imgLR = cv2.imread(imgLRPath) imgHRPath = '../../github/vrn-07231340/examples/trump_12.png' imgHR = cv2.imread(imgHRPath) objPath = '../../github/vrn-07231340/obj/trump_12.obj' '''2. img LR --> HR''' zRatio = 3 objLinesHR, vLinesHR, landmarkLR, landmarkHR = lr2hr3DModel( imgLR, imgHR, zRatio, objPath) '''3. HR: origin 2D landmark --> origin 3D landmark''' originLandmark3DList = getLandmark3DHR(landmarkHR, vLinesHR) originLandmark3DList = optionChooseZMax(originLandmark3DList) faceLandmarkVlines = [] for (_, _, (_, vLine)) in originLandmark3DList: faceLandmarkVlines.append(vLine) '''4. HR: collar detection''' _, collarPoint = collarDetection(imgHR, minSize=1200, offset=15) '''5. HR: hair detection''' originHairPoints = hairDetection(imgHR, minSize=20000) '''5.1 hair vLines z = -1''' hairPointsVlines = [] for (x, y) in originHairPoints: hairVline = '{} {} {} {} {} {} {}'.format('v', x, y, -1, 0, 0, 0) hairPointsVlines.append(hairVline) '''6. HR: origin vLines = face landmark vLines + hair vLines''' originVlines = faceLandmarkVlines+hairPointsVlines '''7. HR: origin points''' originPointsHR = [] for originVline in originVlines: _, x, y, _, _, _, _ = originVline.split() originPointsHR.append((float(x), float(y))) '''8. inner ellipse''' left = min(originPointsHR, key=lambda x: x[0])[0] right = max(originPointsHR, key=lambda x: x[0])[0] up = min(originPointsHR, key=lambda x: x[1])[1] bottom = max(originPointsHR, key=lambda x: x[1])[1] innerEllipseCenterX = int((left+right)/2.0) innerEllipseCenterY = int((up+bottom)/2.0) innerEllipseSemiX = int((right-left)/2.0) innerEllipseSemiY = int((bottom-up)/2.0) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, innerEllipseSemiY, innerEllipseSemiX, orientation=np.pi*1.5) innerEllipseVerts = np.dstack([rr, cc])[0] # drawPointsOnImg(innerEllipseVerts, imgHR, 'g') '''9. outer ellipse''' '''9.1 ratio = outer ellipse / inner ellipse''' ''' 椭圆心和衣领的线段 和 椭圆的交点''' minDistance = np.inf for pt in innerEllipseVerts: distance = twoPointsDistance(pt, collarPoint) if distance < minDistance: minDistance = distance ratio = twoPointsDistance((innerEllipseCenterX, innerEllipseCenterY), collarPoint) / \ twoPointsDistance( (innerEllipseCenterX, innerEllipseCenterY), pt) '''9.2 outer ellipse''' outerEllipseSemiX = int(ratio*innerEllipseSemiX) outerEllipseSemiY = int(ratio*innerEllipseSemiY) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, outerEllipseSemiY, outerEllipseSemiX, orientation=np.pi*1.5) outerEllipseVerts = np.dstack([rr, cc])[0] # drawPointsOnImg(outerEllipseVerts, imgHR, 'r') '''10. head ellipoid (outer ellipse)''' '''!!! F I N A L L Y !!!''' maxminDict = maxminXYZ(vLinesHR) maxZ = maxminDict['maxZCoord'][2] minZ = maxminDict['minZCoord'][2] ellipsoidHeadVLines, ellipsoidHeadXY, ellipsoidHeadXZ, ellipsoidHeadYZ, ellipsoidHeadXYZ = ellipsoidHead( outerEllipseSemiX, outerEllipseSemiY, maxZ - minZ, innerEllipseCenterX, innerEllipseCenterY, minZ) # drawPointsOnImg(ellipsoidHeadXY, imgHR, 'b') # drawPointsOnImg(ellipsoidHeadXZ, imgHR, 'r') # drawPointsOnImg(ellipsoidHeadYZ, imgHR, 'g') '''11. hair vLines: z = -1 --> z on ellipsoid''' newHairPointsVlines = [] for hairPointsVline in hairPointsVlines: v, x, y, z, r, g, b = hairPointsVline.split() maxZ = 0 for (x0, y0, z0) in ellipsoidHeadXYZ: if int(float(x)) == int(float(x0)) and int(float(y)) == int(float(y0)) and float(z0) > 0: # print int(float(x0)), int(float(y0)), int(float(z0)) if int(float(z0)) > int(float(z)) and int(float(z0)) > maxZ: maxZ = int(float(z0)) print maxZ newHairPointsVline = '{} {} {} {} {} {} {}'.format( v, x, y, maxZ, r, g, b) newHairPointsVlines.append(newHairPointsVline) # print hairPointsVlines # print newHairPointsVlines assert len(hairPointsVlines) == len(newHairPointsVlines) '''12. HR: origin vLines = face landmark vLines + new hair vLines''' originVlines = faceLandmarkVlines+newHairPointsVlines '''13. HR: turn face and hair''' turnAngle = 10 turnDirection = ['left', 'right'] turnCenterMode = 'maxY' leftTurnVLines = turnHR(originVlines, turnAngle, turnDirection[0], turnCenterMode) rightTurnVLines = turnHR(originVlines, turnAngle, turnDirection[1], turnCenterMode) assert len(originVlines) == len(leftTurnVLines) == len(rightTurnVLines) '''14. HR: turn 3D --> 2D''' originPointsHR = [] leftTurnPointsHR = [] rightTurnPointsHR = [] for originVline, leftTurnVLine, rightTurnVLine in zip(originVlines, leftTurnVLines, rightTurnVLines): _, x, y, _, _, _, _ = originVline.split() originPointsHR.append((float(x), float(y))) _, x, y, _, _, _, _ = leftTurnVLine.split() leftTurnPointsHR.append((float(x), float(y))) _, x, y, _, _, _, _ = rightTurnVLine.split() rightTurnPointsHR.append((float(x), float(y))) assert len(originPointsHR) == len( leftTurnPointsHR) == len(rightTurnPointsHR) '''15. edge points on outer ellipse''' edgePoints = edgePointsOnOuterEllipse(outerEllipseVerts) '''16. final origin and turn points''' originPointsHRFinal = originPointsHR+edgePoints leftTurnPointsHRFinal = leftTurnPointsHR+edgePoints rightTurnPointsHRFinal = rightTurnPointsHR+edgePoints '''17. tri.txt''' triList = generateTriList( originPointsHRFinal, imgHR, triTxtPath='./turnTri.txt') return originPointsHRFinal, leftTurnPointsHRFinal, rightTurnPointsHRFinal, triList
def mainNodHR(): '''1. read img LR and HR''' imgLRPath = '../../github/vrn-07231340/examples/scaled/trump-12.jpg' imgLR = cv2.imread(imgLRPath) imgHRPath = '../../github/vrn-07231340/examples/trump-12.jpg' imgHR = cv2.imread(imgHRPath) objPath = '../../github/vrn-07231340/obj/trump-12.obj' '''2. img LR --> HR''' zRatio = 3 objLinesHR, vLinesHR, landmarkLR, landmarkHR = lr2hr3DModel( imgLR, imgHR, zRatio, objPath) '''3. HR: origin 2D landmark --> origin 3D landmark''' originLandmark3DList = getLandmark3DHR(landmarkHR, vLinesHR) originLandmark3DList = optionChooseZMax(originLandmark3DList) faceLandmarkVlines = [] for (_, _, (_, vLine)) in originLandmark3DList: faceLandmarkVlines.append(vLine) '''4. HR: collar detection''' _, collarPoint = collarDetection(imgHR, minSize=1200, offset=15) '''5. HR: hair detection''' originHairPoints = hairDetection(imgHR, minSize=20000) # minZ = maxminXYZ(objLinesHR)['minZCoord'][2] minZ = 180 hairPointsVlines = [] for (x, y) in originHairPoints: hairVline = '{} {} {} {} {} {} {}'.format('v', x, y, minZ, 0, 0, 0) hairPointsVlines.append(hairVline) '''6. HR: face landmarks + hair points''' originVlines = faceLandmarkVlines + hairPointsVlines '''7. HR: nod face and hair''' nodAngle = 15 nodCenterMode = 'maxY' nodVlines = nodHR(originVlines, nodAngle, nodCenterMode) assert len(originVlines) == len(nodVlines) '''8. HR: nod 3D --> 2D''' originPointsHR = [] nodPointsHR = [] for originVline, nodVline in zip(originVlines, nodVlines): _, x, y, _, _, _, _ = originVline.split() originPointsHR.append((float(x), float(y))) _, x, y, _, _, _, _ = nodVline.split() nodPointsHR.append((float(x), float(y))) assert len(originPointsHR) == len(nodPointsHR) # drawPointsOnImg(originPointsHR, imgHR, 'g', radius=2) # drawPointsOnImg(nodPointsHR, imgHR, 'r', radius=2) ''''9. inner ellipse''' left = min(originPointsHR, key=lambda x: x[0])[0] right = max(originPointsHR, key=lambda x: x[0])[0] up = min(originPointsHR, key=lambda x: x[1])[1] bottom = max(originPointsHR, key=lambda x: x[1])[1] innerEllipseCenterX = int((left + right) / 2.0) innerEllipseCenterY = int((up + bottom) / 2.0) innerEllipseSemiX = int((right - left) / 2.0) innerEllipseSemiY = int((bottom - up) / 2.0) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, innerEllipseSemiY, innerEllipseSemiX, orientation=np.pi * 1.5) innerEllipseVerts = np.dstack([rr, cc])[0] '''10. outer ellipse''' '''10.1 ratio = outer ellipse / inner ellipse''' ''' 椭圆心和衣领的线段 和 椭圆的交点''' minDistance = np.inf for pt in innerEllipseVerts: distance = twoPointsDistance(pt, collarPoint) if distance < minDistance: minDistance = distance ratio = twoPointsDistance((innerEllipseCenterX, innerEllipseCenterY), collarPoint) / \ twoPointsDistance( (innerEllipseCenterX, innerEllipseCenterY), pt) '''10.2 outer ellipse''' outerEllipseSemiX = int(ratio * innerEllipseSemiX) outerEllipseSemiY = int(ratio * innerEllipseSemiY) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, outerEllipseSemiY, outerEllipseSemiX, orientation=np.pi * 1.5) outerEllipseVerts = np.dstack([rr, cc])[0] '''11. edge points on outer ellipse''' edgePoints = edgePointsOnOuterEllipse(outerEllipseVerts) '''12. final origin and nod points''' originPointsHRFinal = originPointsHR + edgePoints nodPointsHRFinal = nodPointsHR + edgePoints assert len(originPointsHRFinal) == len(nodPointsHRFinal) '''13. tri.txt''' triList = generateTriList(originPointsHRFinal, imgHR, triTxtPath='./nodTri.txt') '''14. warp''' imgMorph = morph_modify_for_2D3D2D_low_resolution(originPointsHRFinal, nodPointsHRFinal, imgHR, triList) imshow('imgMorph', imgMorph) cv2.imwrite('./imgMorph.png', imgMorph) return originPointsHRFinal, nodPointsHRFinal, triList
def main2D_3D_2D_HR_NodHair(): '''1. read origin obj and image''' objPath = '../../github/vrn-07231340/obj/trump-12.obj' objLines, vLines, fLines = readObj(objPath) imgLRPath = '../../github/vrn-07231340/examples/scaled/trump-12.jpg' imgLR = cv2.imread(imgLRPath) imgHRPath = '../../github/vrn-07231340/examples/trump-12.jpg' imgHR = cv2.imread(imgHRPath) '''2. origin LR 2D landmark --> origin 3D landmark''' '''2.1 origin LR 2D landmark list [x, y]''' originLandmark2DLRList = getLandmark2D(imgLR) '''2.2 origin 3D landmark list [[[x, y], [(line1, vLine1), (line2, vLine2)]], ... ]''' originLandmark3DList = getLandmark3D(originLandmark2DLRList, vLines) '''2.3 OPTION 1: 相同(x, y)的情况下,选z最大的3D landmark''' originLandmark3DList = optionChooseZMax(originLandmark3DList) '''3. 3D model nod''' nodAngle = 10 nodCenterMode = 'maxY' nodObjLines = nod(objPath, nodAngle, nodCenterMode) '''4. nod 3D landmark list''' nodVLines = objLines2vLines(nodObjLines) nodLandmark3DList = getNodLandmark3D(nodVLines, originLandmark3DList) '''5. nod 3D landmark --> nod LR 2D landmark''' nodLandmark2DLR = [i[2] for i in nodLandmark3DList] '''6. origin 2D landmark''' originLandmark2DLR = [(i[0][0], i[0][1]) for i in nodLandmark3DList] assert len(originLandmark2DLR) == len(nodLandmark2DLR) '''7. LR --> HR: origin and nod face landmark''' originLandmark2DHR = lr2hr(imgLR, imgHR, originLandmark2DLR) nodLandmark2DHR = lr2hr(imgLR, imgHR, nodLandmark2DLR) '''8. HR: collar detection''' _, collarPoint = collarDetection(imgHR, minSize=1200, offset=15) '''9. HR: hair detection''' originHairPoints = hairDetection(imgHR, minSize=20000) '''10. HR: nod hair points''' '''??? nod center ???''' nodAngleHair = 18 # drawPointsOnImg(originHairPoints, imgHR, 'r', radius=3) # nodHairPoints = nodHairHR( # objLines, nodAngleHair, nodCenterMode, originHairPoints, minZ=100.0) nodHairPoints = nodHairHR_m( nodAngleHair, collarPoint, originHairPoints, minZ=100.0) # for (x, y), (i, j) in zip(nodHairPoints, nodHairPoints_m): # if x == i and y == j: # pass # else: # print 'yes' '''10. HR: all origin points and nod points''' originPoints = originLandmark2DHR+originHairPoints nodPoints = nodLandmark2DHR+nodHairPoints assert len(originPoints) == len(nodPoints) # drawPointsOnImg(originPoints, imgHR, 'g', radius=2) '''11. inner ellipse''' left = min(originPoints, key=lambda x: x[0])[0] right = max(originPoints, key=lambda x: x[0])[0] up = min(originPoints, key=lambda x: x[1])[1] bottom = max(originPoints, key=lambda x: x[1])[1] innerEllipseCenterX = int((left+right)/2.0) innerEllipseCenterY = int((up+bottom)/2.0) innerEllipseSemiX = int((right-left)/2.0) innerEllipseSemiY = int((bottom-up)/2.0) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, innerEllipseSemiY, innerEllipseSemiX, orientation=np.pi*1.5) innerEllipseVerts = np.dstack([rr, cc])[0] '''12. outer ellipse''' '''12.1 ratio = outer ellipse / inner ellipse''' ''' 椭圆心和衣领的线段 和 椭圆的交点''' minDistance = np.inf for pt in innerEllipseVerts: distance = twoPointsDistance(pt, collarPoint) if distance < minDistance: minDistance = distance ratio = twoPointsDistance((innerEllipseCenterX, innerEllipseCenterY), collarPoint) / \ twoPointsDistance( (innerEllipseCenterX, innerEllipseCenterY), pt) '''12.2 outer ellipse''' outerEllipseSemiX = int(ratio*innerEllipseSemiX) outerEllipseSemiY = int(ratio*innerEllipseSemiY) rr, cc = ellipse_perimeter(innerEllipseCenterX, innerEllipseCenterY, outerEllipseSemiY, outerEllipseSemiX, orientation=np.pi*1.5) outerEllipseVerts = np.dstack([rr, cc])[0] '''13. edge points on outer ellipse''' edgePoints = edgePointsOnOuterEllipse(outerEllipseVerts) '''14. final origin and nod HR points ''' originPointsFinal = originPoints+edgePoints nodPointsFinal = nodPoints+edgePoints assert len(originPointsFinal) == len(nodPointsFinal) drawPointsOnImg(originPointsFinal, imgHR, 'b', radius=2) drawPointsOnImg(originPoints, imgHR, 'r', radius=2) drawPointsOnImg(nodPointsFinal, imgHR, 'g', radius=2) '''15. tri.txt''' triList = generateTriList(originPointsFinal, imgHR, triTxtPath='./nodTri.txt') '''16. warp''' imgMorph = morph_modify_for_2D3D2D_low_resolution( originPointsFinal, nodPointsFinal, imgHR, triList) imshow('imgMorph', imgMorph) cv2.imwrite('./imgMorph_{}2.png'.format(nodAngleHair), imgMorph) return originPointsFinal, nodPointsFinal, triList