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 3215 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(). 03217 { 03218 ENTERFUNC; 03219 03220 if (!image1 || !image2) { 03221 throw NullPointerException("NULL image"); 03222 } 03223 03224 if (mode < 0 || mode > 2) { 03225 throw OutofRangeException(0, 2, mode, "invalid mode"); 03226 } 03227 03228 if (!image1->is_complex()) { 03229 image1 = image1->do_fft(); 03230 } 03231 if (!image2->is_complex()) { 03232 image2 = image2->do_fft(); 03233 } 03234 03235 image1->ap2ri(); 03236 image2->ap2ri(); 03237 03238 if (!EMUtil::is_same_size(image1, image2)) { 03239 throw ImageFormatException("images not same sizes"); 03240 } 03241 03242 int image2_nx = image2->get_xsize(); 03243 int image2_ny = image2->get_ysize(); 03244 03245 int rmax = image2_ny / 4 - 1; 03246 int array_size = steps * rmax * 2; 03247 float *im1 = new float[array_size]; 03248 float *im2 = new float[array_size]; 03249 for (int i = 0; i < array_size; i++) { 03250 im1[i] = 0; 03251 im2[i] = 0; 03252 } 03253 03254 set_size(steps * 2, steps * 2, 1); 03255 03256 float *image1_data = image1->get_data(); 03257 float *image2_data = image2->get_data(); 03258 03259 float da = M_PI / steps; 03260 float a = -M_PI / 2.0f + da / 2.0f; 03261 int jmax = 0; 03262 03263 for (int i = 0; i < steps * 2; i += 2, a += da) { 03264 float s1 = 0; 03265 float s2 = 0; 03266 int i2 = i * rmax; 03267 int j = 0; 03268 03269 for (float r = 3.0f; r < rmax - 3.0f; j += 2, r += 1.0f) { 03270 float x = r * cos(a); 03271 float y = r * sin(a); 03272 03273 if (x < 0) { 03274 x = -x; 03275 y = -y; 03276 LOGERR("CCL ERROR %d, %f !\n", i, -x); 03277 } 03278 03279 int k = (int) (floor(x) * 2 + floor(y + image2_ny / 2) * image2_nx); 03280 int l = i2 + j; 03281 float x2 = x - floor(x); 03282 float y2 = y - floor(y); 03283 03284 im1[l] = Util::bilinear_interpolate(image1_data[k], 03285 image1_data[k + 2], 03286 image1_data[k + image2_nx], 03287 image1_data[k + 2 + image2_nx], x2, y2); 03288 03289 im2[l] = Util::bilinear_interpolate(image2_data[k], 03290 image2_data[k + 2], 03291 image2_data[k + image2_nx], 03292 image2_data[k + 2 + image2_nx], x2, y2); 03293 03294 k++; 03295 03296 im1[l + 1] = Util::bilinear_interpolate(image1_data[k], 03297 image1_data[k + 2], 03298 image1_data[k + image2_nx], 03299 image1_data[k + 2 + image2_nx], x2, y2); 03300 03301 im2[l + 1] = Util::bilinear_interpolate(image2_data[k], 03302 image2_data[k + 2], 03303 image2_data[k + image2_nx], 03304 image2_data[k + 2 + image2_nx], x2, y2); 03305 03306 s1 += Util::square_sum(im1[l], im1[l + 1]); 03307 s2 += Util::square_sum(im2[l], im2[l + 1]); 03308 } 03309 03310 jmax = j - 1; 03311 float sqrt_s1 = std::sqrt(s1); 03312 float sqrt_s2 = std::sqrt(s2); 03313 03314 int l = 0; 03315 for (float r = 1; r < rmax; r += 1.0f) { 03316 int i3 = i2 + l; 03317 im1[i3] /= sqrt_s1; 03318 im1[i3 + 1] /= sqrt_s1; 03319 im2[i3] /= sqrt_s2; 03320 im2[i3 + 1] /= sqrt_s2; 03321 l += 2; 03322 } 03323 } 03324 float * data = get_data(); 03325 03326 switch (mode) { 03327 case 0: 03328 for (int m1 = 0; m1 < 2; m1++) { 03329 for (int m2 = 0; m2 < 2; m2++) { 03330 03331 if (m1 == 0 && m2 == 0) { 03332 for (int i = 0; i < steps; i++) { 03333 int i2 = i * rmax * 2; 03334 for (int j = 0; j < steps; j++) { 03335 int l = i + j * steps * 2; 03336 int j2 = j * rmax * 2; 03337 data[l] = 0; 03338 for (int k = 0; k < jmax; k++) { 03339 data[l] += im1[i2 + k] * im2[j2 + k]; 03340 } 03341 } 03342 } 03343 } 03344 else { 03345 int steps2 = steps * m2 + steps * steps * 2 * m1; 03346 03347 for (int i = 0; i < steps; i++) { 03348 int i2 = i * rmax * 2; 03349 for (int j = 0; j < steps; j++) { 03350 int j2 = j * rmax * 2; 03351 int l = i + j * steps * 2 + steps2; 03352 data[l] = 0; 03353 03354 for (int k = 0; k < jmax; k += 2) { 03355 i2 += k; 03356 j2 += k; 03357 data[l] += im1[i2] * im2[j2]; 03358 data[l] += -im1[i2 + 1] * im2[j2 + 1]; 03359 } 03360 } 03361 } 03362 } 03363 } 03364 } 03365 03366 break; 03367 case 1: 03368 for (int m1 = 0; m1 < 2; m1++) { 03369 for (int m2 = 0; m2 < 2; m2++) { 03370 int steps2 = steps * m2 + steps * steps * 2 * m1; 03371 int p1_sign = 1; 03372 if (m1 != m2) { 03373 p1_sign = -1; 03374 } 03375 03376 for (int i = 0; i < steps; i++) { 03377 int i2 = i * rmax * 2; 03378 03379 for (int j = 0; j < steps; j++) { 03380 int j2 = j * rmax * 2; 03381 03382 int l = i + j * steps * 2 + steps2; 03383 data[l] = 0; 03384 float a = 0; 03385 03386 for (int k = 0; k < jmax; k += 2) { 03387 i2 += k; 03388 j2 += k; 03389 03390 #ifdef _WIN32 03391 float a1 = (float) _hypot(im1[i2], im1[i2 + 1]); 03392 #else 03393 float a1 = (float) hypot(im1[i2], im1[i2 + 1]); 03394 #endif //_WIN32 03395 float p1 = atan2(im1[i2 + 1], im1[i2]); 03396 float p2 = atan2(im2[j2 + 1], im2[j2]); 03397 03398 data[l] += Util::angle_sub_2pi(p1_sign * p1, p2) * a1; 03399 a += a1; 03400 } 03401 03402 data[l] /= (float)(a * M_PI / 180.0f); 03403 } 03404 } 03405 } 03406 } 03407 03408 break; 03409 case 2: 03410 for (int m1 = 0; m1 < 2; m1++) { 03411 for (int m2 = 0; m2 < 2; m2++) { 03412 int steps2 = steps * m2 + steps * steps * 2 * m1; 03413 03414 for (int i = 0; i < steps; i++) { 03415 int i2 = i * rmax * 2; 03416 03417 for (int j = 0; j < steps; j++) { 03418 int j2 = j * rmax * 2; 03419 int l = i + j * steps * 2 + steps2; 03420 data[l] = 0; 03421 03422 for (int k = 0; k < jmax; k += 2) { 03423 i2 += k; 03424 j2 += k; 03425 #ifdef _WIN32 03426 data[l] += (float) (_hypot(im1[i2], im1[i2 + 1]) * _hypot(im2[j2], im2[j2 + 1])); 03427 #else 03428 data[l] += (float) (hypot(im1[i2], im1[i2 + 1]) * hypot(im2[j2], im2[j2 + 1])); 03429 #endif //_WIN32 03430 } 03431 } 03432 } 03433 } 03434 } 03435 03436 break; 03437 default: 03438 break; 03439 } 03440 03441 if (horizontal) { 03442 float *tmp_array = new float[ny]; 03443 for (int i = 1; i < nx; i++) { 03444 for (int j = 0; j < ny; j++) { 03445 tmp_array[j] = get_value_at(i, j); 03446 } 03447 for (int j = 0; j < ny; j++) { 03448 set_value_at(i, j, 0, tmp_array[(j + i) % ny]); 03449 } 03450 } 03451 if( tmp_array ) 03452 { 03453 delete[]tmp_array; 03454 tmp_array = 0; 03455 } 03456 } 03457 03458 if( im1 ) 03459 { 03460 delete[]im1; 03461 im1 = 0; 03462 } 03463 03464 if( im2 ) 03465 { 03466 delete im2; 03467 im2 = 0; 03468 } 03469 03470 03471 image1->update(); 03472 image2->update(); 03473 if( image1 ) 03474 { 03475 delete image1; 03476 image1 = 0; 03477 } 03478 if( image2 ) 03479 { 03480 delete image2; 03481 image2 = 0; 03482 } 03483 update(); 03484 EXITFUNC; 03485 }
|
|
Finds common lines between 2 real images.
Definition at line 3489 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(). 03491 { 03492 ENTERFUNC; 03493 03494 if (!image1 || !image2) { 03495 throw NullPointerException("NULL image"); 03496 } 03497 03498 if (!EMUtil::is_same_size(image1, image2)) { 03499 throw ImageFormatException("images not same size"); 03500 } 03501 03502 int steps2 = steps * 2; 03503 int image_ny = image1->get_ysize(); 03504 EMData *image1_copy = image1->copy(); 03505 EMData *image2_copy = image2->copy(); 03506 03507 float *im1 = new float[steps2 * image_ny]; 03508 float *im2 = new float[steps2 * image_ny]; 03509 03510 EMData *images[] = { image1_copy, image2_copy }; 03511 float *ims[] = { im1, im2 }; 03512 03513 for (int m = 0; m < 2; m++) { 03514 float *im = ims[m]; 03515 float a = M_PI / steps2; 03516 Transform t(Dict("type","2d","alpha",-a)); 03517 for (int i = 0; i < steps2; i++) { 03518 images[i]->transform(t); 03519 float *data = images[i]->get_data(); 03520 03521 for (int j = 0; j < image_ny; j++) { 03522 float sum = 0; 03523 for (int k = 0; k < image_ny; k++) { 03524 sum += data[j * image_ny + k]; 03525 } 03526 im[i * image_ny + j] = sum; 03527 } 03528 03529 float sum1 = 0; 03530 float sum2 = 0; 03531 for (int j = 0; j < image_ny; j++) { 03532 int l = i * image_ny + j; 03533 sum1 += im[l]; 03534 sum2 += im[l] * im[l]; 03535 } 03536 03537 float mean = sum1 / image_ny; 03538 float sigma = std::sqrt(sum2 / image_ny - sum1 * sum1); 03539 03540 for (int j = 0; j < image_ny; j++) { 03541 int l = i * image_ny + j; 03542 im[l] = (im[l] - mean) / sigma; 03543 } 03544 03545 images[i]->update(); 03546 a += M_PI / steps; 03547 } 03548 } 03549 03550 set_size(steps2, steps2, 1); 03551 float *data1 = get_data(); 03552 03553 if (horiz) { 03554 for (int i = 0; i < steps2; i++) { 03555 for (int j = 0, l = i; j < steps2; j++, l++) { 03556 if (l == steps2) { 03557 l = 0; 03558 } 03559 03560 float sum = 0; 03561 for (int k = 0; k < image_ny; k++) { 03562 sum += im1[i * image_ny + k] * im2[l * image_ny + k]; 03563 } 03564 data1[i + j * steps2] = sum; 03565 } 03566 } 03567 } 03568 else { 03569 for (int i = 0; i < steps2; i++) { 03570 for (int j = 0; j < steps2; j++) { 03571 float sum = 0; 03572 for (int k = 0; k < image_ny; k++) { 03573 sum += im1[i * image_ny + k] * im2[j * image_ny + k]; 03574 } 03575 data1[i + j * steps2] = sum; 03576 } 03577 } 03578 } 03579 03580 update(); 03581 03582 if( image1_copy ) 03583 { 03584 delete image1_copy; 03585 image1_copy = 0; 03586 } 03587 03588 if( image2_copy ) 03589 { 03590 delete image2_copy; 03591 image2_copy = 0; 03592 } 03593 03594 if( im1 ) 03595 { 03596 delete[]im1; 03597 im1 = 0; 03598 } 03599 03600 if( im2 ) 03601 { 03602 delete[]im2; 03603 im2 = 0; 03604 } 03605 EXITFUNC; 03606 }
|