// File: manikandan5[P]Image-Matching-Stitching-Warping/./Homography.h
// Function: getProjection(Image const&, Image const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void getProjection(const Image& I1,const Image& I2,const string& name)
{	
	SiftDescriptorMap mapping;
	int count = Image::MatchSIFT(I1,I2,mapping);
	
	if(count <4)
	{
		cout<<" Image "<<name<<" cannot be formed due to insufficient Sift matchings"<<endl;
		return ;
	}
	
	assert(count >= 4);
	// We need 4 points to get Projection
	
	//Figure out to find N
	int N = 10000;
		
	int inliners = -1;
	CImg<double> bestProjection;
	for(int i = 0;i<N;++i)
	{
		CImg<double> projection = linearSystemSolver(mapping);
		int numberOfInliners = getInliners(projection,mapping);
		if(numberOfInliners > inliners)
		{
			inliners = numberOfInliners;
			bestProjection = projection;
			//cout<<inliners<<endl;
		}
	}
	
	assert(inliners > 0);		
	//cout<<"Inliners = "<<inliners<<" , size = "<<mapping.size()<<endl;
	
	//Converting 8 X 1 matrix to 3 X 3 matrix
	CImg<double> actualProjection(3,3);
	actualProjection(0,0) = bestProjection(0,0);
	actualProjection(1,0) = bestProjection(0,1);
	actualProjection(2,0) = bestProjection(0,2);
	actualProjection(0,1) = bestProjection(0,3);
	actualProjection(1,1) = bestProjection(0,4);
	actualProjection(2,1) = bestProjection(0,5);
	actualProjection(0,2) = bestProjection(0,6);
	actualProjection(1,2) = bestProjection(0,7);
	actualProjection(2,2) = 1;
		
	projectiveTransform(I1,actualProjection,name);
}

// Assembly:
subq $0x1b8, %rsp            # imm = 0x1B8
movq %rdi, 0x1b0(%rsp)
movq %rsi, 0x1a8(%rsp)
movq %rdx, 0x1a0(%rsp)
leaq 0x188(%rsp), %rdi
movq %rdi, 0xe8(%rsp)
callq 0xb170
movq 0xe8(%rsp), %rdx
movq 0x1b0(%rsp), %rdi
movq 0x1a8(%rsp), %rsi
xorl %ecx, %ecx
callq 0xb180
movl %eax, 0xf4(%rsp)
jmp 0x71cc
movl 0xf4(%rsp), %eax
movl %eax, 0x184(%rsp)
cmpl $0x4, 0x184(%rsp)
jge 0x7281
movq 0xf8dd9(%rip), %rdi     # 0xfffc8
leaq 0xc271e(%rip), %rsi     # 0xc9914
callq 0x5520
movq %rax, 0xe0(%rsp)
jmp 0x7205
movq 0xe0(%rsp), %rdi
movq 0x1a0(%rsp), %rsi
callq 0x54b0
movq %rax, 0xd8(%rsp)
jmp 0x7224
movq 0xd8(%rsp), %rdi
leaq 0xc26e9(%rip), %rsi     # 0xc991c
callq 0x5520
movq %rax, 0xd0(%rsp)
jmp 0x7242
movq 0xd0(%rsp), %rdi
movq 0xf8d4f(%rip), %rsi     # 0xfffa0
callq 0x5580
jmp 0x7258
movl $0x1, 0x170(%rsp)
jmp 0x775b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0x779e
cmpl $0x4, 0x184(%rsp)
jl 0x728d
jmp 0x72ac
leaq 0xc26bd(%rip), %rdi     # 0xc9951
leaq 0xc26c1(%rip), %rsi     # 0xc995c
movl $0x9d, %edx
leaq 0xc26c4(%rip), %rcx     # 0xc996b
callq 0x5350
movl $0x2710, 0x16c(%rsp) # imm = 0x2710
movl $0xffffffff, 0x168(%rsp) # imm = 0xFFFFFFFF
leaq 0x148(%rsp), %rdi
callq 0xb6c0
jmp 0x72d1
movl $0x0, 0x144(%rsp)
movl 0x144(%rsp), %eax
cmpl 0x16c(%rsp), %eax
jge 0x73cc
leaq 0x120(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x65f0
jmp 0x7307
leaq 0x120(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x6df0
movl %eax, 0xcc(%rsp)
jmp 0x7325
movl 0xcc(%rsp), %eax
movl %eax, 0x11c(%rsp)
movl 0x11c(%rsp), %eax
cmpl 0x168(%rsp), %eax
jle 0x73a9
movl 0x11c(%rsp), %eax
movl %eax, 0x168(%rsp)
leaq 0x148(%rsp), %rdi
leaq 0x120(%rsp), %rsi
callq 0xb700
jmp 0x7368
jmp 0x73a9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
jmp 0x7791
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0x120(%rsp), %rdi
callq 0xa540
jmp 0x7791
leaq 0x120(%rsp), %rdi
callq 0xa540
movl 0x144(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x144(%rsp)
jmp 0x72dc
cmpl $0x0, 0x168(%rsp)
jle 0x73d8
jmp 0x73f7
leaq 0xc25cd(%rip), %rdi     # 0xc99ac
leaq 0xc2576(%rip), %rsi     # 0xc995c
movl $0xb1, %edx
leaq 0xc2579(%rip), %rcx     # 0xc996b
callq 0x5350
leaq 0xf8(%rsp), %rdi
movl $0x3, %edx
movl $0x1, %r8d
movl %edx, %esi
movl %r8d, %ecx
callq 0xa580
jmp 0x7416
leaq 0x148(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x9850
movq %rax, 0xc0(%rsp)
jmp 0x7431
movq 0xc0(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0xb0(%rsp)
leaq 0xf8(%rsp), %rdi
xorl %edx, %edx
movl %edx, %esi
callq 0x9850
movq %rax, 0xb8(%rsp)
jmp 0x7461
movq 0xb8(%rsp), %rax
movsd 0xb0(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x9850
movq %rax, 0xa8(%rsp)
jmp 0x7494
movq 0xa8(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x98(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x1, %esi
xorl %edx, %edx
callq 0x9850
movq %rax, 0xa0(%rsp)
jmp 0x74c7
movq 0xa0(%rsp), %rax
movsd 0x98(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x9850
movq %rax, 0x90(%rsp)
jmp 0x74fa
movq 0x90(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x80(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x2, %esi
xorl %edx, %edx
callq 0x9850
movq %rax, 0x88(%rsp)
jmp 0x752d
movq 0x88(%rsp), %rax
movsd 0x80(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x3, %edx
callq 0x9850
movq %rax, 0x78(%rsp)
jmp 0x755d
movq 0x78(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x68(%rsp)
leaq 0xf8(%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x9850
movq %rax, 0x70(%rsp)
jmp 0x7587
movq 0x70(%rsp), %rax
movsd 0x68(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x4, %edx
callq 0x9850
movq %rax, 0x60(%rsp)
jmp 0x75b1
movq 0x60(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x50(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x1, %edx
movl %edx, %esi
callq 0x9850
movq %rax, 0x58(%rsp)
jmp 0x75db
movq 0x58(%rsp), %rax
movsd 0x50(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x5, %edx
callq 0x9850
movq %rax, 0x48(%rsp)
jmp 0x7605
movq 0x48(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x38(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x2, %esi
movl $0x1, %edx
callq 0x9850
movq %rax, 0x40(%rsp)
jmp 0x7632
movq 0x40(%rsp), %rax
movsd 0x38(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x6, %edx
callq 0x9850
movq %rax, 0x30(%rsp)
jmp 0x765c
movq 0x30(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x20(%rsp)
leaq 0xf8(%rsp), %rdi
xorl %esi, %esi
movl $0x2, %edx
callq 0x9850
movq %rax, 0x28(%rsp)
jmp 0x7686
movq 0x28(%rsp), %rax
movsd 0x20(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0x148(%rsp), %rdi
xorl %esi, %esi
movl $0x7, %edx
callq 0x9850
movq %rax, 0x18(%rsp)
jmp 0x76b0
movq 0x18(%rsp), %rax
movsd (%rax), %xmm0
movsd %xmm0, 0x8(%rsp)
leaq 0xf8(%rsp), %rdi
movl $0x1, %esi
movl $0x2, %edx
callq 0x9850
movq %rax, 0x10(%rsp)
jmp 0x76dd
movq 0x10(%rsp), %rax
movsd 0x8(%rsp), %xmm0
movsd %xmm0, (%rax)
leaq 0xf8(%rsp), %rdi
movl $0x2, %edx
movl %edx, %esi
callq 0x9850
movq %rax, (%rsp)
jmp 0x7706
movq (%rsp), %rax
movabsq $0x3ff0000000000000, %rcx # imm = 0x3FF0000000000000
movq %rcx, (%rax)
movq 0x1b0(%rsp), %rdi
movq 0x1a0(%rsp), %rdx
leaq 0xf8(%rsp), %rsi
callq 0x5d10
jmp 0x7736
leaq 0xf8(%rsp), %rdi
callq 0xa540
leaq 0x148(%rsp), %rdi
callq 0xa540
movl $0x0, 0x170(%rsp)
leaq 0x188(%rsp), %rdi
callq 0xb730
addq $0x1b8, %rsp            # imm = 0x1B8
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x178(%rsp)
movl %eax, 0x174(%rsp)
leaq 0xf8(%rsp), %rdi
callq 0xa540
leaq 0x148(%rsp), %rdi
callq 0xa540
leaq 0x188(%rsp), %rdi
callq 0xb730
movq 0x178(%rsp), %rdi
callq 0x5970
nopl (%rax,%rax)