Functions | |
void | EMAN::EMData::common_lines (EMData *image1, EMData *image2, int mode=0, int steps=180, bool horizontal=false) |
Finds common lines between 2 complex images. | |
void | EMAN::EMData::common_lines_real (EMData *image1, EMData *image2, int steps=180, bool horizontal=false) |
Finds common lines between 2 real images. |
void EMData::common_lines | ( | EMData * | image1, | |
EMData * | image2, | |||
int | mode = 0 , |
|||
int | steps = 180 , |
|||
bool | horizontal = false | |||
) | [inherited] |
Finds common lines between 2 complex images.
This function does not assume any symmetry, just blindly compute the "sinogram" and the user has to take care how to interpret the returned "sinogram". it only considers inplane rotation and assumes prefect centering and identical scale.
image1 | The first complex image. | |
image2 | The second complex image. | |
mode | Either 0 or 1 or 2. mode 0 is a summed dot-product, larger value means better match; mode 1 is weighted phase residual, lower value means better match. | |
steps | 1/2 of the resolution of the map. | |
horizontal | In horizontal way or not. |
NullPointerException | If 'image1' or 'image2' is NULL. | |
OutofRangeException | If 'mode' is invalid. | |
ImageFormatException | If 'image1' 'image2' are not same size. |
Definition at line 3429 of file emdata.cpp.
References EMAN::Util::angle_sub_2pi(), EMAN::EMData::ap2ri(), EMAN::Util::bilinear_interpolate(), data, EMAN::EMData::do_fft(), ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), EMAN::EMData::get_value_at(), EMAN::EMData::get_xsize(), EMAN::EMData::get_ysize(), ImageFormatException, EMAN::EMData::is_complex(), EMAN::EMUtil::is_same_size(), LOGERR, NullPointerException, EMAN::EMData::nx, EMAN::EMData::ny, OutofRangeException, EMAN::EMData::set_size(), EMAN::EMData::set_value_at(), sqrt(), EMAN::Util::square_sum(), EMAN::EMData::update(), x, and y.
Referenced by main().
03431 { 03432 ENTERFUNC; 03433 03434 if (!image1 || !image2) { 03435 throw NullPointerException("NULL image"); 03436 } 03437 03438 if (mode < 0 || mode > 2) { 03439 throw OutofRangeException(0, 2, mode, "invalid mode"); 03440 } 03441 03442 if (!image1->is_complex()) { 03443 image1 = image1->do_fft(); 03444 } 03445 if (!image2->is_complex()) { 03446 image2 = image2->do_fft(); 03447 } 03448 03449 image1->ap2ri(); 03450 image2->ap2ri(); 03451 03452 if (!EMUtil::is_same_size(image1, image2)) { 03453 throw ImageFormatException("images not same sizes"); 03454 } 03455 03456 int image2_nx = image2->get_xsize(); 03457 int image2_ny = image2->get_ysize(); 03458 03459 int rmax = image2_ny / 4 - 1; 03460 int array_size = steps * rmax * 2; 03461 float *im1 = new float[array_size]; 03462 float *im2 = new float[array_size]; 03463 for (int i = 0; i < array_size; i++) { 03464 im1[i] = 0; 03465 im2[i] = 0; 03466 } 03467 03468 set_size(steps * 2, steps * 2, 1); 03469 03470 float *image1_data = image1->get_data(); 03471 float *image2_data = image2->get_data(); 03472 03473 float da = M_PI / steps; 03474 float a = -M_PI / 2.0f + da / 2.0f; 03475 int jmax = 0; 03476 03477 for (int i = 0; i < steps * 2; i += 2, a += da) { 03478 float s1 = 0; 03479 float s2 = 0; 03480 int i2 = i * rmax; 03481 int j = 0; 03482 03483 for (float r = 3.0f; r < rmax - 3.0f; j += 2, r += 1.0f) { 03484 float x = r * cos(a); 03485 float y = r * sin(a); 03486 03487 if (x < 0) { 03488 x = -x; 03489 y = -y; 03490 LOGERR("CCL ERROR %d, %f !\n", i, -x); 03491 } 03492 03493 int k = (int) (floor(x) * 2 + floor(y + image2_ny / 2) * image2_nx); 03494 int l = i2 + j; 03495 float x2 = x - floor(x); 03496 float y2 = y - floor(y); 03497 03498 im1[l] = Util::bilinear_interpolate(image1_data[k], 03499 image1_data[k + 2], 03500 image1_data[k + image2_nx], 03501 image1_data[k + 2 + image2_nx], x2, y2); 03502 03503 im2[l] = Util::bilinear_interpolate(image2_data[k], 03504 image2_data[k + 2], 03505 image2_data[k + image2_nx], 03506 image2_data[k + 2 + image2_nx], x2, y2); 03507 03508 k++; 03509 03510 im1[l + 1] = Util::bilinear_interpolate(image1_data[k], 03511 image1_data[k + 2], 03512 image1_data[k + image2_nx], 03513 image1_data[k + 2 + image2_nx], x2, y2); 03514 03515 im2[l + 1] = Util::bilinear_interpolate(image2_data[k], 03516 image2_data[k + 2], 03517 image2_data[k + image2_nx], 03518 image2_data[k + 2 + image2_nx], x2, y2); 03519 03520 s1 += Util::square_sum(im1[l], im1[l + 1]); 03521 s2 += Util::square_sum(im2[l], im2[l + 1]); 03522 } 03523 03524 jmax = j - 1; 03525 float sqrt_s1 = std::sqrt(s1); 03526 float sqrt_s2 = std::sqrt(s2); 03527 03528 int l = 0; 03529 for (float r = 1; r < rmax; r += 1.0f) { 03530 int i3 = i2 + l; 03531 im1[i3] /= sqrt_s1; 03532 im1[i3 + 1] /= sqrt_s1; 03533 im2[i3] /= sqrt_s2; 03534 im2[i3 + 1] /= sqrt_s2; 03535 l += 2; 03536 } 03537 } 03538 float * data = get_data(); 03539 03540 switch (mode) { 03541 case 0: 03542 for (int m1 = 0; m1 < 2; m1++) { 03543 for (int m2 = 0; m2 < 2; m2++) { 03544 03545 if (m1 == 0 && m2 == 0) { 03546 for (int i = 0; i < steps; i++) { 03547 int i2 = i * rmax * 2; 03548 for (int j = 0; j < steps; j++) { 03549 int l = i + j * steps * 2; 03550 int j2 = j * rmax * 2; 03551 data[l] = 0; 03552 for (int k = 0; k < jmax; k++) { 03553 data[l] += im1[i2 + k] * im2[j2 + k]; 03554 } 03555 } 03556 } 03557 } 03558 else { 03559 int steps2 = steps * m2 + steps * steps * 2 * m1; 03560 03561 for (int i = 0; i < steps; i++) { 03562 int i2 = i * rmax * 2; 03563 for (int j = 0; j < steps; j++) { 03564 int j2 = j * rmax * 2; 03565 int l = i + j * steps * 2 + steps2; 03566 data[l] = 0; 03567 03568 for (int k = 0; k < jmax; k += 2) { 03569 i2 += k; 03570 j2 += k; 03571 data[l] += im1[i2] * im2[j2]; 03572 data[l] += -im1[i2 + 1] * im2[j2 + 1]; 03573 } 03574 } 03575 } 03576 } 03577 } 03578 } 03579 03580 break; 03581 case 1: 03582 for (int m1 = 0; m1 < 2; m1++) { 03583 for (int m2 = 0; m2 < 2; m2++) { 03584 int steps2 = steps * m2 + steps * steps * 2 * m1; 03585 int p1_sign = 1; 03586 if (m1 != m2) { 03587 p1_sign = -1; 03588 } 03589 03590 for (int i = 0; i < steps; i++) { 03591 int i2 = i * rmax * 2; 03592 03593 for (int j = 0; j < steps; j++) { 03594 int j2 = j * rmax * 2; 03595 03596 int l = i + j * steps * 2 + steps2; 03597 data[l] = 0; 03598 float a = 0; 03599 03600 for (int k = 0; k < jmax; k += 2) { 03601 i2 += k; 03602 j2 += k; 03603 03604 #ifdef _WIN32 03605 float a1 = (float) _hypot(im1[i2], im1[i2 + 1]); 03606 #else 03607 float a1 = (float) hypot(im1[i2], im1[i2 + 1]); 03608 #endif //_WIN32 03609 float p1 = atan2(im1[i2 + 1], im1[i2]); 03610 float p2 = atan2(im2[j2 + 1], im2[j2]); 03611 03612 data[l] += Util::angle_sub_2pi(p1_sign * p1, p2) * a1; 03613 a += a1; 03614 } 03615 03616 data[l] /= (float)(a * M_PI / 180.0f); 03617 } 03618 } 03619 } 03620 } 03621 03622 break; 03623 case 2: 03624 for (int m1 = 0; m1 < 2; m1++) { 03625 for (int m2 = 0; m2 < 2; m2++) { 03626 int steps2 = steps * m2 + steps * steps * 2 * m1; 03627 03628 for (int i = 0; i < steps; i++) { 03629 int i2 = i * rmax * 2; 03630 03631 for (int j = 0; j < steps; j++) { 03632 int j2 = j * rmax * 2; 03633 int l = i + j * steps * 2 + steps2; 03634 data[l] = 0; 03635 03636 for (int k = 0; k < jmax; k += 2) { 03637 i2 += k; 03638 j2 += k; 03639 #ifdef _WIN32 03640 data[l] += (float) (_hypot(im1[i2], im1[i2 + 1]) * _hypot(im2[j2], im2[j2 + 1])); 03641 #else 03642 data[l] += (float) (hypot(im1[i2], im1[i2 + 1]) * hypot(im2[j2], im2[j2 + 1])); 03643 #endif //_WIN32 03644 } 03645 } 03646 } 03647 } 03648 } 03649 03650 break; 03651 default: 03652 break; 03653 } 03654 03655 if (horizontal) { 03656 float *tmp_array = new float[ny]; 03657 for (int i = 1; i < nx; i++) { 03658 for (int j = 0; j < ny; j++) { 03659 tmp_array[j] = get_value_at(i, j); 03660 } 03661 for (int j = 0; j < ny; j++) { 03662 set_value_at(i, j, 0, tmp_array[(j + i) % ny]); 03663 } 03664 } 03665 if( tmp_array ) 03666 { 03667 delete[]tmp_array; 03668 tmp_array = 0; 03669 } 03670 } 03671 03672 if( im1 ) 03673 { 03674 delete[]im1; 03675 im1 = 0; 03676 } 03677 03678 if( im2 ) 03679 { 03680 delete im2; 03681 im2 = 0; 03682 } 03683 03684 03685 image1->update(); 03686 image2->update(); 03687 if( image1 ) 03688 { 03689 delete image1; 03690 image1 = 0; 03691 } 03692 if( image2 ) 03693 { 03694 delete image2; 03695 image2 = 0; 03696 } 03697 update(); 03698 EXITFUNC; 03699 }
void EMData::common_lines_real | ( | EMData * | image1, | |
EMData * | image2, | |||
int | steps = 180 , |
|||
bool | horizontal = false | |||
) | [inherited] |
Finds common lines between 2 real images.
image1 | The first image. | |
image2 | The second image. | |
steps | 1/2 of the resolution of the map. | |
horizontal | In horizontal way or not. |
NullPointerException | If 'image1' or 'image2' is NULL. | |
ImageFormatException | If 'image1' 'image2' are not same size. |
Definition at line 3703 of file emdata.cpp.
References EMAN::EMData::copy(), data, ENTERFUNC, EXITFUNC, EMAN::EMData::get_data(), ImageFormatException, images, EMAN::EMUtil::is_same_size(), mean(), NullPointerException, EMAN::EMData::set_size(), sqrt(), t, EMAN::EMData::transform(), and EMAN::EMData::update().
Referenced by main().
03705 { 03706 ENTERFUNC; 03707 03708 if (!image1 || !image2) { 03709 throw NullPointerException("NULL image"); 03710 } 03711 03712 if (!EMUtil::is_same_size(image1, image2)) { 03713 throw ImageFormatException("images not same size"); 03714 } 03715 03716 int steps2 = steps * 2; 03717 int image_ny = image1->get_ysize(); 03718 EMData *image1_copy = image1->copy(); 03719 EMData *image2_copy = image2->copy(); 03720 03721 float *im1 = new float[steps2 * image_ny]; 03722 float *im2 = new float[steps2 * image_ny]; 03723 03724 EMData *images[] = { image1_copy, image2_copy }; 03725 float *ims[] = { im1, im2 }; 03726 03727 for (int m = 0; m < 2; m++) { 03728 float *im = ims[m]; 03729 float a = M_PI / steps2; 03730 Transform t(Dict("type","2d","alpha",-a)); 03731 for (int i = 0; i < steps2; i++) { 03732 images[i]->transform(t); 03733 float *data = images[i]->get_data(); 03734 03735 for (int j = 0; j < image_ny; j++) { 03736 float sum = 0; 03737 for (int k = 0; k < image_ny; k++) { 03738 sum += data[j * image_ny + k]; 03739 } 03740 im[i * image_ny + j] = sum; 03741 } 03742 03743 float sum1 = 0; 03744 float sum2 = 0; 03745 for (int j = 0; j < image_ny; j++) { 03746 int l = i * image_ny + j; 03747 sum1 += im[l]; 03748 sum2 += im[l] * im[l]; 03749 } 03750 03751 float mean = sum1 / image_ny; 03752 float sigma = std::sqrt(sum2 / image_ny - sum1 * sum1); 03753 03754 for (int j = 0; j < image_ny; j++) { 03755 int l = i * image_ny + j; 03756 im[l] = (im[l] - mean) / sigma; 03757 } 03758 03759 images[i]->update(); 03760 a += M_PI / steps; 03761 } 03762 } 03763 03764 set_size(steps2, steps2, 1); 03765 float *data1 = get_data(); 03766 03767 if (horiz) { 03768 for (int i = 0; i < steps2; i++) { 03769 for (int j = 0, l = i; j < steps2; j++, l++) { 03770 if (l == steps2) { 03771 l = 0; 03772 } 03773 03774 float sum = 0; 03775 for (int k = 0; k < image_ny; k++) { 03776 sum += im1[i * image_ny + k] * im2[l * image_ny + k]; 03777 } 03778 data1[i + j * steps2] = sum; 03779 } 03780 } 03781 } 03782 else { 03783 for (int i = 0; i < steps2; i++) { 03784 for (int j = 0; j < steps2; j++) { 03785 float sum = 0; 03786 for (int k = 0; k < image_ny; k++) { 03787 sum += im1[i * image_ny + k] * im2[j * image_ny + k]; 03788 } 03789 data1[i + j * steps2] = sum; 03790 } 03791 } 03792 } 03793 03794 update(); 03795 03796 if( image1_copy ) 03797 { 03798 delete image1_copy; 03799 image1_copy = 0; 03800 } 03801 03802 if( image2_copy ) 03803 { 03804 delete image2_copy; 03805 image2_copy = 0; 03806 } 03807 03808 if( im1 ) 03809 { 03810 delete[]im1; 03811 im1 = 0; 03812 } 03813 03814 if( im2 ) 03815 { 03816 delete[]im2; 03817 im2 = 0; 03818 } 03819 EXITFUNC; 03820 }