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