<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl">
	<id>http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mlew</id>
	<title>Brain-wiki - Wkład użytkownika [pl]</title>
	<link rel="self" type="application/atom+xml" href="http://brain.fuw.edu.pl/edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mlew"/>
	<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php/Specjalna:Wk%C5%82ad/Mlew"/>
	<updated>2026-04-14T17:13:36Z</updated>
	<subtitle>Wkład użytkownika</subtitle>
	<generator>MediaWiki 1.34.1</generator>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6226</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6226"/>
		<updated>2016-12-14T19:10:41Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego.&lt;br /&gt;
Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA. Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją w Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy.&amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
Przedstawienie metod obrazowania tłumienia można znaleźć w pracach dr Z.Klimondy.&amp;lt;ref&amp;gt;http://www.ippt.pan.pl/staff/zklim&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat Synthetic Transmit Aperture (STA) polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy.&amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Coś z Dopplera?==&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6225</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6225"/>
		<updated>2016-12-14T19:09:48Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego.&lt;br /&gt;
Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA. Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją w Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy.&amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
Przedstawienie metod obrazowania tłumienia można znaleźć w pracach dr Z.Klimondy.&amp;lt;ref&amp;gt;http://www.ippt.pan.pl/staff/zklim&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat Synthetic Transmit Aperture (STA) polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy.&amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6224</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6224"/>
		<updated>2016-12-14T19:07:46Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Obrazowanie metodą Synthetic Transmit Aperture */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego.&lt;br /&gt;
Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA. Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją w Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy.&amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
Przedstawienie metod obrazowania tłumienia można znaleźć w pracach dr Z.Klimondy.&amp;lt;ref&amp;gt;http://www.ippt.pan.pl/staff/zklim&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy.&amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6223</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6223"/>
		<updated>2016-12-14T19:07:17Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Short-lag Spatial Coherence */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego.&lt;br /&gt;
Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA. Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją w Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy.&amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
Przedstawienie metod obrazowania tłumienia można znaleźć w pracach dr Z.Klimondy.&amp;lt;ref&amp;gt;http://www.ippt.pan.pl/staff/zklim&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy.&amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6222</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6222"/>
		<updated>2016-12-14T19:06:40Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego.&lt;br /&gt;
Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA. Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją w Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
Przedstawienie metod obrazowania tłumienia można znaleźć w pracach dr Z.Klimondy.&amp;lt;ref&amp;gt;http://www.ippt.pan.pl/staff/zklim&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy.&amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6221</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6221"/>
		<updated>2016-12-14T19:01:02Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu, algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego. Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA.&lt;br /&gt;
Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem, służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy &amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6220</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6220"/>
		<updated>2016-12-14T19:00:11Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
Zaliczenie warsztatów wymaga realizacji jednego z poniżej zaproponowanych projektów zespołowych (2-3 os.). Celem projektów jest implementacja i przetestowanie wybranej metody obrazowania/przetwarzania sygnału USG. &lt;br /&gt;
Studenci mają samodzielnie zaimplementować algorytm korzystając z powołanych publikacji lub źródeł internetowych. W zależności od tematu algorytmy będą testowane bezpośrednio na edukacyjnym systemie ultrasonografu lub na dostarczonych danych. Istnieje także możliwość samodzielnego zebrania danych z fantomu tkankowego. Na zakończenie każdy zespół przygotuje i wygłosi krótką prezentację (10-15 slajdów), która przedstawi zrealizowany projekt i osiągnięte rezultaty.&lt;br /&gt;
&lt;br /&gt;
==Implementacja OpenCL metod obrazowych==&lt;br /&gt;
Zadanie polega na zaimplementowaniu i optymalizacji w OpenCL jednej z metod rekonstrukcji obrazu B-mode: metody klasycznego beamformingu, metody PWI, metody STA.&lt;br /&gt;
Rezultaty algorytmu równoległego w OpenCL muszą zostać zweryfikowane i porównane z implementacją Python.&lt;br /&gt;
Integracja zaimplementowanego kodu ze skryptem, służącym do odbierania danych surowych z edukacyjnego systemu USG, powinna pozwolić na uzyskanie obrazowania w czasie rzeczywistym.&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy &amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6219</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6219"/>
		<updated>2016-12-14T18:39:52Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
&lt;br /&gt;
'''Warsztaty z metod obrazowania ultradźwiękowego''' są autorskim programem&amp;lt;ref&amp;gt;z inicjatywy dr Marcina Lewandowskiego z Instytutu Podstawowych Problemów Techniki PAN; opracowanie materiałów przy współpracy z Tomaszem Steiferem&amp;lt;/ref&amp;gt; obejmującym metody i algorytmy obrazowania USG, budowę i funkcje aparatury USG oraz wprowadzenie do programowania równoległego na procesorach GPU w środowisku OpenCL. &lt;br /&gt;
Dzięki dofinansowaniu otrzymanemu z ''Funduszu Innowacji Dydaktycznych'' UW opracowano materiały oraz zakupiono edukacyjny system ultrasonografu, który umożliwia zbierania surowych sygnałów i testowanie własnych algorytmów przetwarzania sygnałów.&lt;br /&gt;
&lt;br /&gt;
===Opis===&lt;br /&gt;
Ultrasonografia stanowi najpowszechniej stosowaną modalność diagnostyczną we współczesnej medycynie. Kurs ma na celu zapoznanie studentów z szerokim spektrum metod i zastosowań ultradźwięków w diagnostyce medycznej. Metody te obejmują standardowe obrazowanie USG, obrazowanie parametryczne, elastografię, metody oceny przepływu krwi i inne. Zajęcia będą podzielone na część wykładową (ok. 1/3 czasu) i warsztatową (ok. 2/3 czasu).&lt;br /&gt;
&lt;br /&gt;
Zagadnienia części wykładowej:&lt;br /&gt;
#Ultradźwięki – zagadnienia generacji, propagacji fal ultradźwiękowych, zjawiska falowe.&lt;br /&gt;
#Zagadnienia tworzenia obrazu USG; metody elektronicznego sterowania i ogniskowania wiązki; metoda beamformingu.&lt;br /&gt;
#Nowe metody syntetycznej apertury w obrazowaniu; obrazowanie 3D/4D.&lt;br /&gt;
#Wybrane inne techniki obrazowe (np. elastografia, obrazowanie tłumienia).&lt;br /&gt;
#Podstawy metod oceny i pomiaru przepływu krwi.&lt;br /&gt;
#Prezentacja wybranych zastosowań USG i metod dopplerowskich w praktyce medycznej.&lt;br /&gt;
#Programowanie równoległe, architektura procesorów CPU/GPU, środowiska CUDA/OpenCL, narzędzia.&lt;br /&gt;
#Budowa i funkcje aparatury USG, zagadnienia zapewnienia jakości, certyfikacji wyrobów.&lt;br /&gt;
&lt;br /&gt;
W części warsztatowej studenci będą zespołowo implementować wybrane metody przetwarzania - m.in. klasyczną rekonstrukcję obrazu, rekonstrukcję w obrazowaniu falą płaską czy obrazowanie prędkości przepływu metodą dopplerowską. Studenci zapoznają się z algorytmami obróbki sygnałów ultradźwiękowych oraz zagadnieniami ich implementacji i optymalizacji. Praca w części warsztatowej odbywać będzie się w grupach (2-3 osoby).&lt;br /&gt;
Zwieńczeniem kursu będzie realizacja projektów zespołowych. Projekty te będą obejmować implementację własnych algorytmów przetwarzania surowych sygnałów ech ultradźwiękowych w oparciu o samodzielnie zebrane dane z uniwersalnej platformy ultrasonografu. Podstawą uzyskania pozytywnej oceny będzie wykonanie zadań z części warsztatowej oraz zaliczenie projektu (raport lub prezentacja).&lt;br /&gt;
&lt;br /&gt;
===Oprogramowanie i konfiguracja do ćwiczeń===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
*[[USG/Rozwiązania|Rozwiązania]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
*[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6218</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6218"/>
		<updated>2016-12-14T18:39:03Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
&lt;br /&gt;
'''Warsztaty z metod obrazowania ultradźwiękowego''' są autorskim programem&amp;lt;ref&amp;gt;z inicjatywy dr Marcina Lewandowskiego z Instytutu Podstawowych Problemów Techniki PAN; opracowanie materiałów przy współpracy z Tomaszem Steiferem&amp;lt;/ref&amp;gt; obejmującym metody i algorytmy obrazowania USG, budowę i funkcje aparatury USG oraz wprowadzenie do programowania równoległego na procesorach GPU w środowisku OpenCL. &lt;br /&gt;
Dzięki dofinansowaniu otrzymanemu z ''Funduszu Innowacji Dydaktycznych'' UW opracowano materiały oraz zakupiono edukacyjny system ultrasonografu, który umożliwia zbierania surowych sygnałów i testowanie własnych algorytmów przetwarzania sygnałów.&lt;br /&gt;
&lt;br /&gt;
===Opis===&lt;br /&gt;
Ultrasonografia stanowi najpowszechniej stosowaną modalność diagnostyczną we współczesnej medycynie. Kurs ma na celu zapoznanie studentów z szerokim spektrum metod i zastosowań ultradźwięków w diagnostyce medycznej. Metody te obejmują standardowe obrazowanie USG, obrazowanie parametryczne, elastografię, metody oceny przepływu krwi i inne. Zajęcia będą podzielone na część wykładową (ok. 1/3 czasu) i warsztatową (ok. 2/3 czasu).&lt;br /&gt;
&lt;br /&gt;
Zagadnienia części wykładowej:&lt;br /&gt;
#Ultradźwięki – zagadnienia generacji, propagacji fal ultradźwiękowych, zjawiska falowe.&lt;br /&gt;
#Zagadnienia tworzenia obrazu USG; metody elektronicznego sterowania i ogniskowania wiązki; metoda beamformingu.&lt;br /&gt;
#Nowe metody syntetycznej apertury w obrazowaniu; obrazowanie 3D/4D.&lt;br /&gt;
#Wybrane inne techniki obrazowe (np. elastografia, obrazowanie tłumienia).&lt;br /&gt;
#Podstawy metod oceny i pomiaru przepływu krwi.&lt;br /&gt;
#Prezentacja wybranych zastosowań USG i metod dopplerowskich w praktyce medycznej.&lt;br /&gt;
#Programowanie równoległe, architektura procesorów CPU/GPU, środowiska CUDA/OpenCL, narzędzia.&lt;br /&gt;
#Budowa i funkcje aparatury USG, zagadnienia zapewnienia jakości, certyfikacji wyrobów.&lt;br /&gt;
&lt;br /&gt;
W części warsztatowej studenci będą zespołowo implementować wybrane metody przetwarzania - m.in. klasyczną rekonstrukcję obrazu, rekonstrukcję w obrazowaniu falą płaską czy obrazowanie prędkości przepływu metodą dopplerowską. Studenci zapoznają się z algorytmami obróbki sygnałów ultradźwiękowych oraz zagadnieniami ich implementacji i optymalizacji. Praca w części warsztatowej odbywać będzie się w grupach (2-3 osoby).&lt;br /&gt;
Zwieńczeniem kursu będzie realizacja projektów zespołowych. Projekty te będą obejmować implementację własnych algorytmów przetwarzania surowych sygnałów ech ultradźwiękowych w oparciu o samodzielnie zebrane dane z uniwersalnej platformy ultrasonografu. Podstawą uzyskania pozytywnej oceny będzie wykonanie zadań z części warsztatowej oraz zaliczenie projektu (raport lub prezentacja).&lt;br /&gt;
&lt;br /&gt;
===Oprogramowanie i konfiguracja do ćwiczeń===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
*[[USG/Rozwiązania|Rozwiązania]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
*[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6217</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6217"/>
		<updated>2016-12-14T18:38:25Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Wstęp */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
&lt;br /&gt;
'''Warsztaty z metod obrazowania ultradźwiękowego''' są autorskim programem&amp;lt;ref&amp;gt;z inicjatywy dr Marcina Lewandowskiego z Instytutu Podstawowych Problemów Techniki PAN; opracowanie materiałów przy współpracy z Tomaszem Steiferem&amp;lt;/ref&amp;gt; obejmującym metody i algorytmy obrazowania USG, budowę i funkcje aparatury USG oraz wprowadzenie do programowania równoległego na procesorach GPU w środowisku OpenCL. &lt;br /&gt;
Dzięki dofinansowaniu otrzymanemu z ''Funduszu Innowacji Dydaktycznych'' UW opracowano materiały oraz zakupiono edukacyjny system ultrasonografu, który umożliwia zbierania surowych sygnałów i testowanie własnych algorytmów przetwarzania sygnałów.&lt;br /&gt;
&lt;br /&gt;
===Opis===&lt;br /&gt;
Ultrasonografia stanowi najpowszechniej stosowaną modalność diagnostyczną we współczesnej medycynie. Kurs ma na celu zapoznanie studentów z szerokim spektrum metod i zastosowań ultradźwięków w diagnostyce medycznej. Metody te obejmują standardowe obrazowanie USG, obrazowanie parametryczne, elastografię, metody oceny przepływu krwi i inne. Zajęcia będą podzielone na część wykładową (ok. 1/3 czasu) i warsztatową (ok. 2/3 czasu).&lt;br /&gt;
&lt;br /&gt;
Zagadnienia części wykładowej:&lt;br /&gt;
#Ultradźwięki – zagadnienia generacji, propagacji fal ultradźwiękowych, zjawiska falowe.&lt;br /&gt;
#Zagadnienia tworzenia obrazu USG; metody elektronicznego sterowania i ogniskowania wiązki; metoda beamformingu.&lt;br /&gt;
#Nowe metody syntetycznej apertury w obrazowaniu; obrazowanie 3D/4D.&lt;br /&gt;
#Wybrane inne techniki obrazowe (np. elastografia, obrazowanie tłumienia).&lt;br /&gt;
#Podstawy metod oceny i pomiaru przepływu krwi.&lt;br /&gt;
#Prezentacja wybranych zastosowań USG i metod dopplerowskich w praktyce medycznej.&lt;br /&gt;
#Programowanie równoległe, architektura procesorów CPU/GPU, środowiska CUDA/OpenCL, narzędzia.&lt;br /&gt;
#Budowa i funkcje aparatury USG, zagadnienia zapewnienia jakości, certyfikacji wyrobów.&lt;br /&gt;
&lt;br /&gt;
W części warsztatowej studenci będą zespołowo implementować wybrane metody przetwarzania - m.in. klasyczną rekonstrukcję obrazu, rekonstrukcję w obrazowaniu falą płaską czy obrazowanie prędkości przepływu metodą dopplerowską. Studenci zapoznają się z algorytmami obróbki sygnałów ultradźwiękowych oraz zagadnieniami ich implementacji i optymalizacji. Praca w części warsztatowej odbywać będzie się w grupach (2-3 osoby).&lt;br /&gt;
Zwieńczeniem kursu będzie realizacja projektów zespołowych. Projekty te będą obejmować implementację własnych algorytmów przetwarzania surowych sygnałów ech ultradźwiękowych w oparciu o samodzielnie zebrane dane z uniwersalnej platformy ultrasonografu. Podstawą uzyskania pozytywnej oceny będzie wykonanie zadań z części warsztatowej oraz zaliczenie projektu (raport lub prezentacja).&lt;br /&gt;
&lt;br /&gt;
===Oprogramowanie i konfiguracja do ćwiczeń===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
*[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
*[[USG/Rozwiązania|Rozwiązania]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6216</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6216"/>
		<updated>2016-12-14T18:36:19Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
&lt;br /&gt;
'''Warsztaty z metod obrazowania ultradźwiękowego''' są autorskim programem&amp;lt;ref&amp;gt;z inicjatywy dr Marcina Lewandowskiego z Instytutu Podstawowych Problemów Techniki PAN; opracowanie materiałów przy współpracy z Tomaszem Steiferem&amp;lt;/ref&amp;gt; obejmującym metody i algorytmy obrazowania USG, budowę i funkcje aparatury USG oraz wprowadzenie do programowania równoległego na procesorach GPU w środowisku OpenCL. &lt;br /&gt;
Dzięki dofinansowaniu otrzymanemu z ''Funduszu Innowacji Dydaktycznych'' UW opracowano materiały oraz zakupiono edukacyjny system ultrasonografu, który umożliwia zbierania surowych sygnałów i testowanie własnych algorytmów przetwarzania sygnałów.&lt;br /&gt;
&lt;br /&gt;
===Opis===&lt;br /&gt;
Ultrasonografia stanowi najpowszechniej stosowaną modalność diagnostyczną we współczesnej medycynie. Kurs ma na celu zapoznanie studentów z szerokim spektrum metod i zastosowań ultradźwięków w diagnostyce medycznej. Metody te obejmują standardowe obrazowanie USG, obrazowanie parametryczne, elastografię, metody oceny przepływu krwi i inne. Zajęcia będą podzielone na część wykładową (ok. 1/3 czasu) i warsztatową (ok. 2/3 czasu).&lt;br /&gt;
&lt;br /&gt;
Zagadnienia części wykładowej:&lt;br /&gt;
#Ultradźwięki –zagadnienia generacji, propagacji fal ultradźwiękowych, zjawiska falowe.&lt;br /&gt;
#Zagadnienia tworzenia obrazu USG; metody elektronicznego sterowania i ogniskowania wiązki; metoda beamformingu.&lt;br /&gt;
#Nowe metody syntetycznej apertury w obrazowaniu; obrazowanie 3D/4D.&lt;br /&gt;
#Wybrane inne techniki obrazowe (np. elastografia, obrazowanie tłumienia).&lt;br /&gt;
#Podstawy metod oceny i pomiaru przepływu krwi.&lt;br /&gt;
#Prezentacja wybranych zastosowań USG i metod dopplerowskich w praktyce medycznej.&lt;br /&gt;
#Programowanie równoległe, architektura procesorów CPU/GPU, środowiska CUDA/OpenCL, narzędzia.&lt;br /&gt;
#Budowa i funkcje aparatury USG, zagadnienia zapewnienia jakości, certyfikacji wyrobów.&lt;br /&gt;
&lt;br /&gt;
W części warsztatowej studenci będą zespołowo implementować wybrane metody przetwarzania - m.in. klasyczną rekonstrukcję obrazu, rekonstrukcję w obrazowaniu falą płaską czy obrazowanie prędkości przepływu metodą dopplerowską. Studenci zapoznają się z algorytmami obróbki sygnałów ultradźwiękowych oraz zagadnieniami ich implementacji i optymalizacji. Praca w części warsztatowej odbywać będzie się w grupach (2-3 osoby).&lt;br /&gt;
Zwieńczeniem kursu będzie realizacja projektów zespołowych. Projekty te będą obejmować implementację własnych algorytmów przetwarzania surowych sygnałów ech ultradźwiękowych w oparciu o samodzielnie zebrane dane z uniwersalnej platformy ultrasonografu. Podstawą uzyskania pozytywnej oceny będzie wykonanie zadań z części warsztatowej oraz zaliczenie projektu (raport lub prezentacja).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Oprogramowanie i konfiguracja do ćwiczeń===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
#[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
#[[USG/Rozwiązania|Rozwiązania]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6215</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6215"/>
		<updated>2016-12-14T18:34:28Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
&lt;br /&gt;
'''Warsztaty z metod obrazowania ultradźwiękowego''' są autorskim programem&amp;lt;ref&amp;gt;z inicjatywy dr Marcina Lewandowskiego z Instytutu Podstawowych Problemów Techniki PAN; opracowanie materiałów przy współpracy z Tomaszem Steiferem&amp;lt;/ref&amp;gt; obejmującym metody i algorytmy obrazowania USG, budowę i funkcje aparatury USG oraz wprowadzenie do programowania równoległego na procesorach GPU w środowisku OpenCL. &lt;br /&gt;
Dzięki dofinansowaniu otrzymanemu z Funduszu Innowacji Dydaktycznych UW opracowano materiały oraz zakupiono edukacyjny system ultrasonografu, który umożliwia zbierania surowych sygnałów i testowanie własnych algorytmów przetwarzania sygnałów.&lt;br /&gt;
&lt;br /&gt;
===Opis===&lt;br /&gt;
Ultrasonografia stanowi najpowszechniej stosowaną modalność diagnostyczną we współczesnej medycynie. Kurs ma na celu zapoznanie studentów z szerokim spektrum metod i zastosowań ultradźwięków w diagnostyce medycznej. Metody te obejmują standardowe obrazowanie USG, obrazowanie parametryczne, elastografię, metody oceny przepływu krwi i inne. Zajęcia będą podzielone na część wykładową (ok. 1/3 czasu) i warsztatową (ok. 2/3 czasu).&lt;br /&gt;
&lt;br /&gt;
Zagadnienia części wykładowej:&lt;br /&gt;
#Ultradźwięki –zagadnienia generacji, propagacji fal ultradźwiękowych, zjawiska falowe.&lt;br /&gt;
#Zagadnienia tworzenia obrazu USG; metody elektronicznego sterowania i ogniskowania wiązki; metoda beamformingu.&lt;br /&gt;
#Nowe metody syntetycznej apertury w obrazowaniu; obrazowanie 3D/4D.&lt;br /&gt;
#Wybrane inne techniki obrazowe (np. elastografia, obrazowanie tłumienia).&lt;br /&gt;
#Podstawy metod oceny i pomiaru przepływu krwi.&lt;br /&gt;
#Prezentacja wybranych zastosowań USG i metod dopplerowskich w praktyce medycznej.&lt;br /&gt;
#Programowanie równoległe, architektura procesorów CPU/GPU, środowiska CUDA/OpenCL, narzędzia.&lt;br /&gt;
#Budowa i funkcje aparatury USG, zagadnienia zapewnienia jakości, certyfikacji wyrobów.&lt;br /&gt;
&lt;br /&gt;
W części warsztatowej studenci będą zespołowo implementować wybrane metody przetwarzania - m.in. klasyczną rekonstrukcję obrazu, rekonstrukcję w obrazowaniu falą płaską czy obrazowanie prędkości przepływu metodą dopplerowską. Studenci zapoznają się z algorytmami obróbki sygnałów ultradźwiękowych oraz zagadnieniami ich implementacji i optymalizacji. Praca w części warsztatowej odbywać będzie się w grupach (2-3 osoby).&lt;br /&gt;
Zwieńczeniem kursu będzie realizacja projektów zespołowych. Projekty te będą obejmować implementację własnych algorytmów przetwarzania surowych sygnałów ech ultradźwiękowych w oparciu o samodzielnie zebrane dane z uniwersalnej platformy ultrasonografu. Podstawą uzyskania pozytywnej oceny będzie wykonanie zadań z części warsztatowej oraz zaliczenie projektu (raport lub prezentacja).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Oprogramowanie i konfiguracja do ćwiczeń===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
#[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
#[[USG/Rozwiązania|Rozwiązania]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6214</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6214"/>
		<updated>2016-12-14T17:53:04Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp=&lt;br /&gt;
123&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy &amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6213</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6213"/>
		<updated>2016-12-14T17:52:32Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;qqq&lt;br /&gt;
&lt;br /&gt;
==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy &amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6212</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=6212"/>
		<updated>2016-12-14T17:52:19Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie metodą Synthetic Transmit Aperture==&lt;br /&gt;
Schemat STA polega na schemacie nadawczym-odbiorczym: jeden przetwornik nadaje, wszystkie odbierają. Rekonstrukcja obrazu B-mode odbywa się w sposób analogiczny jak w metodzie PWI omówionej na zajęciach. Dokładny opis metody i wzory potrzebne do rekonstrukcji można znaleźć w pracy &amp;lt;ref&amp;gt;Ihor Trots, Andrzej Nowicki, Marcin Lewandowski and Yuriy Tasinkevych (2011). Synthetic Aperture Method in Ultrasound Imaging, Ultrasound Imaging, Mr Masayuki Tanabe (Ed.), InTech, DOI: 10.5772/15986. Available from: http://www.intechopen.com/books/ultrasound-imaging/synthetic-aperture-method-in-ultrasound-imaging&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6012</id>
		<title>USG/Wyklad OpenCL</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6012"/>
		<updated>2016-11-16T18:23:25Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wykład OpenCL=&lt;br /&gt;
&lt;br /&gt;
Do wykładu o programowaniu równoległym procesorów GPU w środowisku OpenCL będziemy korzystać z materiałów &amp;quot;Hands On OpenCL&amp;quot;&amp;lt;ref&amp;gt;https://handsonopencl.github.io/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Zakres tych materiałów daleko wykracza poza zaplanowane w ramach warsztatów &amp;quot;wprowadzenie do programowania w OpenCL&amp;quot;. Dlatego, zainteresowanych zachęcam do samodzielnego zapoznania się z całością tych materiałów.&lt;br /&gt;
&lt;br /&gt;
Polecam także materiały do kursu &amp;quot;GPU programming with PyOpenCL and PyCUDA&amp;quot;&amp;lt;ref&amp;gt;https://www.bu.edu/pasi/courses/gpu-programming-with-pyopencl-and-pycuda/&amp;lt;/ref&amp;gt; autorstwa Dr. Andreas Klöckner, które prezentują wykorzystanie Pythona i modułów PyOpenCL/PyCUDA do programowania GPU.&lt;br /&gt;
&lt;br /&gt;
==Literatura i Linki==&lt;br /&gt;
# David R. Kaeli, Perhaad Mistry, Dana Schaa, Dong Ping Zhang, Heterogeneous Computing with OpenCL 2.0, Morgan Kaufmann, 2015.&lt;br /&gt;
# Matthew Scarpino, OpenCL in Action: How to accelerate graphics and computation, Manning Publications; 1 edition, 2011.&lt;br /&gt;
# Norm Matloff, Programming on Parallel Machines, University of California&amp;lt;ref&amp;gt;http://heather.cs.ucdavis.edu/~matloff/158/PLN/ParProcBook.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
# AMD OpenCL™ Accelerated Parallel Processing Software Development Kit (APP SDK)&amp;lt;ref&amp;gt;http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/documentation&amp;lt;/ref&amp;gt;&lt;br /&gt;
# NVIDIA OpenCL Programming Guide&amp;lt;ref&amp;gt;http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf&amp;lt;/ref&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6011</id>
		<title>USG/Wyklad OpenCL</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6011"/>
		<updated>2016-11-16T18:21:43Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wykład OpenCL=&lt;br /&gt;
&lt;br /&gt;
Do wykładu o programowaniu równoległym procesorów GPU w środowisku OpenCL będziemy korzystać z materiałów &amp;quot;Hands On OpenCL&amp;quot;&amp;lt;ref&amp;gt;https://handsonopencl.github.io/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Zakres tych materiałów daleko wykracza poza zaplanowane w ramach warsztatów &amp;quot;wprowadzenie do programowania w OpenCL&amp;quot;. Dlatego, zainteresowanych zachęcam do samodzielnego zapoznania się z całością tych materiałów.&lt;br /&gt;
&lt;br /&gt;
Polecam także materiały do kursu &amp;quot;GPU programming with PyOpenCL and PyCUDA&amp;quot;&amp;lt;ref&amp;gt;https://www.bu.edu/pasi/courses/gpu-programming-with-pyopencl-and-pycuda/&amp;lt;/ref&amp;gt; autorstwa Dr. Andreas Klöckner, które prezentują wykorzystanie Pythona i modułów PyOpenCL/PyCUDA do programowania GPU.&lt;br /&gt;
&lt;br /&gt;
==Literatura i Linki==&lt;br /&gt;
# David R. Kaeli, Perhaad Mistry, Dana Schaa, Dong Ping Zhang, Heterogeneous Computing with OpenCL 2.0, Morgan Kaufmann, 2015.&lt;br /&gt;
# Matthew Scarpino, OpenCL in Action: How to accelerate graphics and computation, Manning Publications; 1 edition, 2011.&lt;br /&gt;
# Norm Matloff, Programming on Parallel Machines, University of California&amp;lt;ref&amp;gt;heather.cs.ucdavis.edu/~matloff/158/PLN/ParProcBook.pdf&amp;lt;/ref&amp;gt;&lt;br /&gt;
# AMD OpenCL™ Accelerated Parallel Processing Software Development Kit (APP SDK)&amp;lt;ref&amp;gt;http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/documentation&amp;lt;/ref&amp;gt;&lt;br /&gt;
# NVIDIA OpenCL Programming Guide&amp;lt;ref&amp;gt;http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf&amp;lt;/ref&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6010</id>
		<title>USG/Wyklad OpenCL</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6010"/>
		<updated>2016-11-16T18:10:03Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wykład OpenCL=&lt;br /&gt;
&lt;br /&gt;
Do wykładu o programowaniu równoległym procesorów GPU w środowisku OpenCL będziemy korzystać z materiałów &amp;quot;Hands On OpenCL&amp;quot;&amp;lt;ref&amp;gt;https://handsonopencl.github.io/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Zakres tych materiałów daleko wykracza poza zaplanowane w ramach warsztatów &amp;quot;wprowadzenie do programowania w OpenCL&amp;quot;. Dlatego, zainteresowanych zachęcam do samodzielnego zapoznania się z całością tych materiałów.&lt;br /&gt;
&lt;br /&gt;
Polecam także materiały do kursu &amp;quot;GPU programming with PyOpenCL and PyCUDA&amp;quot;&amp;lt;ref&amp;gt;https://www.bu.edu/pasi/courses/gpu-programming-with-pyopencl-and-pycuda/&amp;lt;/ref&amp;gt; autorstwa Dr. Andreas Klöckner, które prezentują wykorzystanie Pythona i modułów PyOpenCL/PyCUDA do programowania GPU.&lt;br /&gt;
&lt;br /&gt;
==Literatura i Linki==&lt;br /&gt;
# David R. Kaeli, Perhaad Mistry, Dana Schaa, Dong Ping Zhang, Heterogeneous Computing with OpenCL 2.0, Morgan Kaufmann, 2015.&lt;br /&gt;
# Matthew Scarpino, OpenCL in Action: How to accelerate graphics and computation, Manning Publications; 1 edition, 2011.&lt;br /&gt;
# AMD OpenCL™ Accelerated Parallel Processing Software Development Kit (APP SDK)&amp;lt;ref&amp;gt;http://developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/documentation&amp;lt;/ref&amp;gt;&lt;br /&gt;
# NVIDIA OpenCL Programming Guide&amp;lt;ref&amp;gt;http://www.nvidia.com/content/cudazone/download/OpenCL/NVIDIA_OpenCL_ProgrammingGuide.pdf&amp;lt;/ref&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6009</id>
		<title>USG/Wyklad OpenCL</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6009"/>
		<updated>2016-11-16T18:02:02Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wykład OpenCL=&lt;br /&gt;
&lt;br /&gt;
Do wykładu o programowaniu równoległym procesorów GPU w środowisku OpenCL będziemy korzystać z materiałów &amp;quot;Hands On OpenCL&amp;quot;&amp;lt;ref&amp;gt;https://handsonopencl.github.io/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Zakres tych materiałów daleko wykracza poza zaplanowane w ramach warsztatów &amp;quot;wprowadzenie do programowania w OpenCL&amp;quot;. Dlatego, zainteresowanych zachęcam do samodzielnego zapoznania się z całością tych materiałów.&lt;br /&gt;
&lt;br /&gt;
Polecam także materiały do kursu &amp;quot;GPU programming with PyOpenCL and PyCUDA&amp;quot;&amp;lt;ref&amp;gt;https://www.bu.edu/pasi/courses/gpu-programming-with-pyopencl-and-pycuda/&amp;lt;/ref&amp;gt; autorstwa Dr. Andreas Klöckner, które prezentują wykorzystanie Pythona i modułów PyOpenCL/PyCUDA do programowania GPU.&lt;br /&gt;
&lt;br /&gt;
==Literatura i Linki==&lt;br /&gt;
# David R. Kaeli, Perhaad Mistry, Dana Schaa, Dong Ping Zhang, Heterogeneous Computing with OpenCL 2.0, Morgan Kaufmann, 2015.&lt;br /&gt;
# Matthew Scarpino, OpenCL in Action: How to accelerate graphics and computation, Manning Publications; 1 edition, 2011.&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6008</id>
		<title>USG/Wyklad OpenCL</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Wyklad_OpenCL&amp;diff=6008"/>
		<updated>2016-11-16T17:49:57Z</updated>

		<summary type="html">&lt;p&gt;Mlew: Utworzenie&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wykład OpenCL=&lt;br /&gt;
&lt;br /&gt;
Do wykładu o programowaniu równoległym procesorów GPU w środowisku OpenCL będziemy korzystać z materiałów &amp;quot;Hands On OpenCL&amp;quot;&amp;lt;ref&amp;gt;https://handsonopencl.github.io/&amp;lt;/ref&amp;gt;.&lt;br /&gt;
Zakres tych materiałów daleko wykracza poza zaplanowane w ramach warsztatów &amp;quot;wprowadzenie do programowania w OpenCL&amp;quot;. Zainteresowanych zachęcam do samodzielnego zapoznania się z tymi materiałami.&lt;br /&gt;
&lt;br /&gt;
==LITERATURA i LINKI==&lt;br /&gt;
# David R. Kaeli, Perhaad Mistry, Dana Schaa, Dong Ping Zhang, Heterogeneous Computing with OpenCL 2.0, Morgan Kaufmann, 2015.&lt;br /&gt;
# x&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6007</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6007"/>
		<updated>2016-11-16T17:36:24Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Pracownia USG=&lt;br /&gt;
&lt;br /&gt;
===Wstępna konfiguracja===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
#[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
#[[USG/Rozwiązania|Rozwiązania]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6006</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=6006"/>
		<updated>2016-11-16T17:28:32Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Pracownia USG=&lt;br /&gt;
&lt;br /&gt;
===Wstępna konfiguracja===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Wykłady==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Wyklad_Fizyka_USG|Podstawy fizyczne USG]]&lt;br /&gt;
#[[USG/Wyklad_Metody_USG|Metody USG]]&lt;br /&gt;
#[[USG/Wyklad_Aparatura_i_Aplikacje|Aparatura i aplikacje medyczne]]&lt;br /&gt;
#[[USG/Wyklad_OpenCL|Programowanie równoległe procesorów GPU w OpenCL]]&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
#[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;br /&gt;
&lt;br /&gt;
==Rozwiązania do ćwiczeń==&lt;br /&gt;
#[[USG/Rozwiązania|Rozwiązania]]&lt;br /&gt;
&lt;br /&gt;
== ==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5566</id>
		<title>USG/PWI</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5566"/>
		<updated>2016-07-27T17:41:27Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Obrazowanie falą płaską */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Obrazowanie falą płaską==&lt;br /&gt;
W obrazowaniu fala płaską (ang. PWI - Plane Wave Imaging) wektor opóźnień nadawczych ma postać prostej, co pozwala uformować wiązkę o płaskim froncie falowym. W odróżnieniu do rozważanej wcześniej metody klasycznego beamformingu, wiązka taka jest nieogniskowana. O froncie falowym w PWI możemy myśleć jak o froncie fali pochodzącej ze źródła punktowego (ognisko wirtualne) położonego względnie daleko za aperturą (w tym sensie, że różnice w czasach przejścia od ogniska wirtualnego do różnych przetworników nadawczych są pomijalne).&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_falaplaska.png|200px|thumb|right|Schemat ilustrujący nadanie falą płaską pod różnymi kątami]]&lt;br /&gt;
&lt;br /&gt;
O ile nie ograniczają nas możliwości techniczne sprzętu (np. mała moc obliczeniowa), w PWI staramy się nadawać i odbierać pełną aperturą. Punktem wyjścia jest fala płaska nadawana pod kątem zerowym względem apertury. Takiemu schematowi nadawczemu odpowiada wektor opóźnień określony funkcją stałą (wszystkie przetworniki nadają w tym samym momencie). Obrót wykresu opóźnień nadawczych odpowiada zmianie kąta nadawczego.&lt;br /&gt;
Do stworzenia obrazu ultradźwiękowego wystarczą nam dane zebrane dla pojedynczego nadania (z jednego kąta). W praktyce jednak wykonuje się kilka pomiarów (nadań, strzałów itp.) dla kilku rożnych kątów - pozwala to uzyskać poprawę zarówno rozdzielczości punktowej obrazu, jak i poprawę kontrastu i zwiększenie stosunku sygnału do szumu (SNR - Signal-to-Noise Ratio). &lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
na = 3 # Liczba nadań&lt;br /&gt;
theta = [ -1.74532925e-01 , -1.39626340e-01,  -1.04719755e-01,  -6.98131701e-02,&lt;br /&gt;
  -3.49065850e-02,  -2.77555756e-17,   3.49065850e-02 ,  6.98131701e-02,&lt;br /&gt;
   1.04719755e-01  , 1.39626340e-01  , 1.74532925e-01] # kąty dla kolejnych nadań&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników w pełnej aperturze&lt;br /&gt;
Ntr = 192 # Pełna subapertura nadawcza&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Surowe dane RF===&lt;br /&gt;
Do dyspozycji mamy ponownie dwa pliki z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_nitki.npy usg2_nitki.npy]) i cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_cysty.npy usg2_cysty.npy]). W każdym pliku znajduje się trójwymiarowa tablica &amp;lt;math&amp;gt;NT\times N \times na &amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji (maksymalnej głębokości obrazowanej) danych z pojedynczego nadania. &amp;lt;br&amp;gt;&lt;br /&gt;
Kluczowe dla dalszych obliczeń będzie wyznaczenie chwili zerowej, czyli momentu rozpoczęcia akwizycji danych. Na różnych urządzeniach przyjmowane są różne konwencje - czasami akwizycja danych rozpoczyna się w momencie, gdy rozpoczyna się nadawanie; czasami akwizycja rozpoczyna się jeszcze przed nadawaniem. &amp;lt;br&amp;gt;&lt;br /&gt;
Zadanie: proszę wyświetlić surowe dane RF (funkcja plot) dla kilku kolejnych nadań i spróbować określić (w przybliżeniu) w jakim momencie rozpoczyna się akwizycja danych:&lt;br /&gt;
a) przed rozpoczęciem nadawania&lt;br /&gt;
b) w momencie rozpoczęcia nadawania&lt;br /&gt;
c) w chwili gdy nadała połowa przetworników&lt;br /&gt;
&lt;br /&gt;
===Rekonstrukcja obrazu z pojedynczego strzału===&lt;br /&gt;
W przypadku klasycznej rekonstrukcji dokonywaliśmy najpierw przesunięcia w czasie próbek RF, a następnie przesunięty (syntezowany) obraz interpolowaliśmy do siatki odpowiadającej rzeczywistym proporcjom obrazowanej struktury. W przypadku PWI wygodniej będzie nam najpierw określić siatkę, a następnie dla kolejnych punktów na tej siatce liczyć wartość pikseli.&lt;br /&gt;
Poniższy kod wygeneruje dwie tablice, w których przechowywane są współrzędne poziome i pionowe w [m] kolejnych punktów siatki. Siatka jest generowana przy założeniu, że punkt (0,0) znajduje się w środku apertury. Cztery próbki na długość fali powinny wystarczyć do otrzymania wystarczająco dobrej jakości obrazu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
halfWidth = 0.02 # Połowa szerokości obrazowania [m] &lt;br /&gt;
lmbda = c/fs&lt;br /&gt;
step=lmbda/4.&lt;br /&gt;
maxdepth = N*c/(fs*2) # maksymalna głębokość [m]&lt;br /&gt;
mindepth = 0.005 # minimalna głębokość [m]&lt;br /&gt;
&lt;br /&gt;
X0 = np.arange(-halfWidth,halfWidth,ar)&lt;br /&gt;
R0 = np.arange(mindepth,maxdepth,br)&lt;br /&gt;
Grid_div_x,Grid_div_z = np.meshgrid(X0,R0,indexing='xy') # tablice ze współrzędnymi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak wcześniej sygnał w punkcie (x,y) będziemy liczyć jako sumę sygnałów z każdego przetwornika odbiorczego odpowiednio opóźnionych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S(x,y)=\sum^{NT-1}_{k=0} s_k(t_{tr}(x,y)+t_k(x,y)) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_k(i)&amp;lt;/math&amp;gt; to sygnał z danego przetwornika odbiorczego; &amp;lt;math&amp;gt;t_{tr}(x,y)&amp;lt;/math&amp;gt; czas przejścia fali do punktu obrazowania; &amp;lt;math&amp;gt;t_k(x,y)&amp;lt;/math&amp;gt; czas przejścia fali odbitej z punktu do przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Dla ustalonego przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; i punktu (x,y) opóźnienie liczone jest jako czas przejścia fali od początku nadania do punktu i z powrotem do danego przetwornika odbiorczego. &lt;br /&gt;
W przypadku PWI możemy założyć, że dla kąta nadawczego &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;t_{tr}(x,y) = (x\cdot sin(\theta)+y\cdot cos(\theta))/c + t_{start} + d &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; jest pewnym przesunięciem stałym dla danego nadania - wyznaczonym przez położenie chwili zerowej (moment rozpoczęcia akwizycji). &lt;br /&gt;
&lt;br /&gt;
Do wykonania&lt;br /&gt;
# Stworzyć funkcję, która dla zadanej siatki obliczać będzie wartości energii dla pojedynczego strzału z danego kąta. Podobnie jak wcześniej, interesuje nas obraz w skali decybelowej z ograniczoną dynamiką.&lt;br /&gt;
# Porównać obraz syntezowany dla zadanej wcześniej siatki z obrazem syntezowanym dla siatki o dwukrotnie większych odległościach między punktami&lt;br /&gt;
&lt;br /&gt;
===Apodyzacja po stronie odbiorczej===&lt;br /&gt;
Standardową metodą poprawy jakości obrazu jest zastosowanie apodyzacji po stronie odbiorczej. W czasie rekonstrukcji natężenie w danym punkcie liczyliśmy jako sumę sygnałów z pojedynczych przetworników odbiorczych. Sygnały z pojedynczych przetworników zawierają jednak informację pochodzącą nie tylko z rozproszenia w danym punkcie. Ponadto, dla dwóch różnych przetworników odbiorczych energia sygnału pochodząca z rozproszenia z danego punktu niekoniecznie musi stanowić taką samą cześć całkowitej energii sygnału. W celu zbadania tego zjawiska:&lt;br /&gt;
# Stworzyć funkcję, która dla zadanego punktu liczy sygnał jako sumę sygnałów tylko z wybranej części przetworników odbiorczych (np. wybranych 12 przetworników). Proszę porównać otrzymane obrazy dla kilku wybranych subapertur odbiorczych (np. pierwsze 12 przetworników, środkowe 12 przetworników i ostatnie 12 przetworników - licząc od lewego końca apertury). Jak bardzo różnią się te obrazy między sobą i jak różnią się od obrazu otrzymanego z pełnej apertury odbiorczej? &lt;br /&gt;
&lt;br /&gt;
Możemy zauważyć, że więcej informacji o danym punkcie zawierają przetworniki położone bliżej tego punktu niż przetworniki położone dalej. Apodyzacja po stronie odbiorczej polega na zastosowaniu przy rekonstrukcji wag, które będą odpowiednio proporcjonalne do odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
# Proszę zaimplementować zmodyfikowany algorytm rekonstrukcji wykorzystujący jakąś wybraną formę apodyzacji odbiorczej, gdzie sumowane sygnały z pojedynczych przetworników odbiorczych będą ważone wartościami niemalejącej funkcji od odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
&lt;br /&gt;
===Złożenie (compounding) obrazów z nadań pod różnymi kątami===&lt;br /&gt;
Jednym z prostych sposobów poprawienia obrazu jest złożenie ze sobą (np. przez średnią arytmetyczną) kilku obrazów z różnych kątów nadawczych.&lt;br /&gt;
&lt;br /&gt;
# Zaimplementować procedurę uśredniającą obrazy otrzymane z kilku kątów nadawczych. &lt;br /&gt;
# Zbadać obraz zrekonstruowany dla wybranego niezerowego kąta nadawczego i spróbować odpowiedzieć na pytanie: czy dla wszystkich punktów na siatce rekonstrukcja jest sensowna? Czy są punkty, które należałoby pominąć w procesie rekonstrukcji/sumowania przy składaniu obrazów z wielu kątów?&lt;br /&gt;
&lt;br /&gt;
===Literatura===&lt;br /&gt;
#Tanter, Mickael, and Mathias Fink. &amp;quot;Ultrafast imaging in biomedical ultrasound.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 61.1 (2014): 102-119.&lt;br /&gt;
#Cikes, Maja, et al. &amp;quot;Ultrafast cardiac ultrasound imaging: Technical principles, applications, and clinical benefits.&amp;quot; JACC: Cardiovascular Imaging 7.8 (2014): 812-823.&lt;br /&gt;
#Montaldo, Gabriel, et al. &amp;quot;Coherent plane-wave compounding for very high frame rate ultrasonography and transient elastography.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 56.3 (2009): 489-506.&lt;br /&gt;
#Smith, Warren J. Modern optical engineering. Tata McGraw-Hill Education, 1966.&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5565</id>
		<title>USG/PWI</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5565"/>
		<updated>2016-07-27T17:40:19Z</updated>

		<summary type="html">&lt;p&gt;Mlew: /* Obrazowanie falą płaską */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Obrazowanie falą płaską==&lt;br /&gt;
W obrazowaniu fala płaską (ang. PWI - Plane Wave Imaging) wektor opóźnień nadawczych ma postać prostej, co pozwala uformować wiązkę o płaskim froncie falowym. W odróżnieniu do rozważanej wcześniej metody klasycznego beamformingu, wiązka taka jest nieogniskowana. O froncie falowym w PWI możemy myśleć jak o froncie fali pochodzącej ze źródła punktowego (ognisko wirtualne) położonego względnie daleko za aperturą (w tym sensie, że różnice w czasach przejścia od ogniska wirtualnego do różnych przetworników nadawczych są pomijalne).&amp;lt;br&amp;gt;&lt;br /&gt;
O ile nie ograniczają nas możliwości techniczne sprzętu (np. mała moc obliczeniowa), w PWI staramy się nadawać i odbierać pełną aperturą. Punktem wyjścia jest fala płaska nadawana pod kątem zerowym względem apertury. Takiemu schematowi nadawczemu odpowiada wektor opóźnień określony funkcją stałą (wszystkie przetworniki nadają w tym samym momencie). Obrót wykresu opóźnień nadawczych odpowiada zmianie kąta nadawczego.&lt;br /&gt;
[[Plik:Rys_falaplaska.png|200px|thumb|right|Schemat ilustrujący nadanie falą płaską pod różnymi kątami]]&lt;br /&gt;
Do stworzenia obrazu ultradźwiękowego wystarczą nam dane zebrane dla pojedynczego nadania (z jednego kąta). W praktyce jednak wykonuje się kilka pomiarów (nadań, strzałów itp.) dla kilku rożnych kątów - pozwala to uzyskać poprawę zarówno rozdzielczości punktowej obrazu, jak i poprawę kontrastu i zwiększenie stosunku sygnału do szumu (SNR - Signal-to-Noise Ratio). &lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
na = 3 # Liczba nadań&lt;br /&gt;
theta = [ -1.74532925e-01 , -1.39626340e-01,  -1.04719755e-01,  -6.98131701e-02,&lt;br /&gt;
  -3.49065850e-02,  -2.77555756e-17,   3.49065850e-02 ,  6.98131701e-02,&lt;br /&gt;
   1.04719755e-01  , 1.39626340e-01  , 1.74532925e-01] # kąty dla kolejnych nadań&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników w pełnej aperturze&lt;br /&gt;
Ntr = 192 # Pełna subapertura nadawcza&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Surowe dane RF===&lt;br /&gt;
Do dyspozycji mamy ponownie dwa pliki z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_nitki.npy usg2_nitki.npy]) i cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_cysty.npy usg2_cysty.npy]). W każdym pliku znajduje się trójwymiarowa tablica &amp;lt;math&amp;gt;NT\times N \times na &amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji (maksymalnej głębokości obrazowanej) danych z pojedynczego nadania. &amp;lt;br&amp;gt;&lt;br /&gt;
Kluczowe dla dalszych obliczeń będzie wyznaczenie chwili zerowej, czyli momentu rozpoczęcia akwizycji danych. Na różnych urządzeniach przyjmowane są różne konwencje - czasami akwizycja danych rozpoczyna się w momencie, gdy rozpoczyna się nadawanie; czasami akwizycja rozpoczyna się jeszcze przed nadawaniem. &amp;lt;br&amp;gt;&lt;br /&gt;
Zadanie: proszę wyświetlić surowe dane RF (funkcja plot) dla kilku kolejnych nadań i spróbować określić (w przybliżeniu) w jakim momencie rozpoczyna się akwizycja danych:&lt;br /&gt;
a) przed rozpoczęciem nadawania&lt;br /&gt;
b) w momencie rozpoczęcia nadawania&lt;br /&gt;
c) w chwili gdy nadała połowa przetworników&lt;br /&gt;
&lt;br /&gt;
===Rekonstrukcja obrazu z pojedynczego strzału===&lt;br /&gt;
W przypadku klasycznej rekonstrukcji dokonywaliśmy najpierw przesunięcia w czasie próbek RF, a następnie przesunięty (syntezowany) obraz interpolowaliśmy do siatki odpowiadającej rzeczywistym proporcjom obrazowanej struktury. W przypadku PWI wygodniej będzie nam najpierw określić siatkę, a następnie dla kolejnych punktów na tej siatce liczyć wartość pikseli.&lt;br /&gt;
Poniższy kod wygeneruje dwie tablice, w których przechowywane są współrzędne poziome i pionowe w [m] kolejnych punktów siatki. Siatka jest generowana przy założeniu, że punkt (0,0) znajduje się w środku apertury. Cztery próbki na długość fali powinny wystarczyć do otrzymania wystarczająco dobrej jakości obrazu.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
halfWidth = 0.02 # Połowa szerokości obrazowania [m] &lt;br /&gt;
lmbda = c/fs&lt;br /&gt;
step=lmbda/4.&lt;br /&gt;
maxdepth = N*c/(fs*2) # maksymalna głębokość [m]&lt;br /&gt;
mindepth = 0.005 # minimalna głębokość [m]&lt;br /&gt;
&lt;br /&gt;
X0 = np.arange(-halfWidth,halfWidth,ar)&lt;br /&gt;
R0 = np.arange(mindepth,maxdepth,br)&lt;br /&gt;
Grid_div_x,Grid_div_z = np.meshgrid(X0,R0,indexing='xy') # tablice ze współrzędnymi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak wcześniej sygnał w punkcie (x,y) będziemy liczyć jako sumę sygnałów z każdego przetwornika odbiorczego odpowiednio opóźnionych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S(x,y)=\sum^{NT-1}_{k=0} s_k(t_{tr}(x,y)+t_k(x,y)) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_k(i)&amp;lt;/math&amp;gt; to sygnał z danego przetwornika odbiorczego; &amp;lt;math&amp;gt;t_{tr}(x,y)&amp;lt;/math&amp;gt; czas przejścia fali do punktu obrazowania; &amp;lt;math&amp;gt;t_k(x,y)&amp;lt;/math&amp;gt; czas przejścia fali odbitej z punktu do przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Dla ustalonego przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; i punktu (x,y) opóźnienie liczone jest jako czas przejścia fali od początku nadania do punktu i z powrotem do danego przetwornika odbiorczego. &lt;br /&gt;
W przypadku PWI możemy założyć, że dla kąta nadawczego &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;t_{tr}(x,y) = (x\cdot sin(\theta)+y\cdot cos(\theta))/c + t_{start} + d &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; jest pewnym przesunięciem stałym dla danego nadania - wyznaczonym przez położenie chwili zerowej (moment rozpoczęcia akwizycji). &lt;br /&gt;
&lt;br /&gt;
Do wykonania&lt;br /&gt;
# Stworzyć funkcję, która dla zadanej siatki obliczać będzie wartości energii dla pojedynczego strzału z danego kąta. Podobnie jak wcześniej, interesuje nas obraz w skali decybelowej z ograniczoną dynamiką.&lt;br /&gt;
# Porównać obraz syntezowany dla zadanej wcześniej siatki z obrazem syntezowanym dla siatki o dwukrotnie większych odległościach między punktami&lt;br /&gt;
&lt;br /&gt;
===Apodyzacja po stronie odbiorczej===&lt;br /&gt;
Standardową metodą poprawy jakości obrazu jest zastosowanie apodyzacji po stronie odbiorczej. W czasie rekonstrukcji natężenie w danym punkcie liczyliśmy jako sumę sygnałów z pojedynczych przetworników odbiorczych. Sygnały z pojedynczych przetworników zawierają jednak informację pochodzącą nie tylko z rozproszenia w danym punkcie. Ponadto, dla dwóch różnych przetworników odbiorczych energia sygnału pochodząca z rozproszenia z danego punktu niekoniecznie musi stanowić taką samą cześć całkowitej energii sygnału. W celu zbadania tego zjawiska:&lt;br /&gt;
# Stworzyć funkcję, która dla zadanego punktu liczy sygnał jako sumę sygnałów tylko z wybranej części przetworników odbiorczych (np. wybranych 12 przetworników). Proszę porównać otrzymane obrazy dla kilku wybranych subapertur odbiorczych (np. pierwsze 12 przetworników, środkowe 12 przetworników i ostatnie 12 przetworników - licząc od lewego końca apertury). Jak bardzo różnią się te obrazy między sobą i jak różnią się od obrazu otrzymanego z pełnej apertury odbiorczej? &lt;br /&gt;
&lt;br /&gt;
Możemy zauważyć, że więcej informacji o danym punkcie zawierają przetworniki położone bliżej tego punktu niż przetworniki położone dalej. Apodyzacja po stronie odbiorczej polega na zastosowaniu przy rekonstrukcji wag, które będą odpowiednio proporcjonalne do odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
# Proszę zaimplementować zmodyfikowany algorytm rekonstrukcji wykorzystujący jakąś wybraną formę apodyzacji odbiorczej, gdzie sumowane sygnały z pojedynczych przetworników odbiorczych będą ważone wartościami niemalejącej funkcji od odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
&lt;br /&gt;
===Złożenie (compounding) obrazów z nadań pod różnymi kątami===&lt;br /&gt;
Jednym z prostych sposobów poprawienia obrazu jest złożenie ze sobą (np. przez średnią arytmetyczną) kilku obrazów z różnych kątów nadawczych.&lt;br /&gt;
&lt;br /&gt;
# Zaimplementować procedurę uśredniającą obrazy otrzymane z kilku kątów nadawczych. &lt;br /&gt;
# Zbadać obraz zrekonstruowany dla wybranego niezerowego kąta nadawczego i spróbować odpowiedzieć na pytanie: czy dla wszystkich punktów na siatce rekonstrukcja jest sensowna? Czy są punkty, które należałoby pominąć w procesie rekonstrukcji/sumowania przy składaniu obrazów z wielu kątów?&lt;br /&gt;
&lt;br /&gt;
===Literatura===&lt;br /&gt;
#Tanter, Mickael, and Mathias Fink. &amp;quot;Ultrafast imaging in biomedical ultrasound.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 61.1 (2014): 102-119.&lt;br /&gt;
#Cikes, Maja, et al. &amp;quot;Ultrafast cardiac ultrasound imaging: Technical principles, applications, and clinical benefits.&amp;quot; JACC: Cardiovascular Imaging 7.8 (2014): 812-823.&lt;br /&gt;
#Montaldo, Gabriel, et al. &amp;quot;Coherent plane-wave compounding for very high frame rate ultrasonography and transient elastography.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 56.3 (2009): 489-506.&lt;br /&gt;
#Smith, Warren J. Modern optical engineering. Tata McGraw-Hill Education, 1966.&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=Plik:Rys_falaplaska.png&amp;diff=5564</id>
		<title>Plik:Rys falaplaska.png</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=Plik:Rys_falaplaska.png&amp;diff=5564"/>
		<updated>2016-07-27T17:39:25Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5527</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5527"/>
		<updated>2016-07-05T07:41:26Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska impulsowa (Pulsed Wave)=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdej próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). Dla naszych danych wystarczający powinien być filtr o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację z pewnej objętości pomiarowej, co wynika z kształtu wiązki ultradźwiękowej).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego sygnału zespolonego.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
# flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie.&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji).&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/GPU&amp;diff=5526</id>
		<title>USG/GPU</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/GPU&amp;diff=5526"/>
		<updated>2016-07-03T12:31:44Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp do obliczeń równoległych na GPU=&lt;br /&gt;
W tej części ćwiczeń stworzymy pierwszy program wykorzystujący bibliotekę OpenCL do obliczeń na kartach graficznych. &lt;br /&gt;
Posłużymy się pythonowym wrapperem do OpenCL - biblioteką PyOpencl. Same kernele będziemy pisać w języku C, ale wszystkie dodatkowe procedury będziemy mogli pisać przy użyciu standardowych poleceń Pythona.&lt;br /&gt;
Zaczniemy od stworzenia prostego programu sumującego dwie tablice liczb zmiennoprzecinkowych i następnie mnożącego tę sumę przez pewien ustalony mnożnik.&lt;br /&gt;
Na sam początek importujemy bibliotekę:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import pyopencl as cl&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kod OpenCL przechowywać będziemy w postaci zmiennej tekstowej. Stworzymy prosty kernel, który dostaje wejściu dwie tablice o wymiarach odpowiednio &amp;lt;math&amp;gt;N\times M\times 2&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt; oraz zmienną z mnożnikiem. Kernel wykorzystywać będzie &amp;lt;math&amp;gt;N\cdot M&amp;lt;/math&amp;gt; jednostek obliczeniowych. Pierwsza tablica zawiera nasze dane wejściowe (ostatni wymiar koduje indeks tablicy wejściowej); druga tablica będzie tablicą w której przechowywać będziemy wynik obliczeń. Przykładowy kernel zdefiniowany jest poniżej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
kernels=&amp;quot;&lt;br /&gt;
        __kernel void Sum(__global float *in, __global float *out, const float add)&lt;br /&gt;
        {&lt;br /&gt;
        //zaczynamy od zadeklarowania zmiennych&lt;br /&gt;
        const int n = get_global_id(0); //indeks w pierwszym wymiarze danej jednostki roboczej&lt;br /&gt;
        const int m = get_global_id(1); //indeks w drugim wymiarze danej jednostki roboczej&lt;br /&gt;
        const int M = get_global_size(1); &lt;br /&gt;
        const int nm = n*M + m; // indeks w tablicy wyjsciowej odpowiadajacy wartości o współrzędnych (n,m)&lt;br /&gt;
        __private int index1; // indeks w zmiennej wejsciowej odpowiadajacy wartości o współrzędnych (n,m,0) &lt;br /&gt;
        __private int index2; // indeks w zmiennej wejsciowej odpowiadajacy wartości o współrzędnych (n,m,1) &lt;br /&gt;
        index1 = 0 + m * 2 + n * M  * 2;&lt;br /&gt;
        index2 = 1 + m * 2 + n * M  * 2;&lt;br /&gt;
        out[nm] = (in[index1]+in[index2]) * add;&lt;br /&gt;
        }&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu wywołania kernela będziemy musieli przygotować środowisko OpenCL, skompilować kod OpenCL (za pomocą odpowiednich funkcji w Pythonie) oraz zarezerwować miejsce w pamięci i przesłać dane do bufora pamięci na GPU.&lt;br /&gt;
Na początek sprawdzimy jakie procesory mamy do dyspozycji&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
platform = cl.get_platforms()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę wypisać zmienną platform. Zależnie od sprzętu i oprogramowania do dyspozycji będziemy mieli jedną lub więcej platform (gdy np. mamy proces Intela i kartę graficzną AMD) wraz z określoną liczbą urządzeń na każdej platformie. Dostępne urządzenia na pierwszej platformie możemy podejrzeć wywołując:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print(platform[0].get_devices())&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wybierzemy jedno z urządzeń i skompilujemy nasz kernel do obliczeń na tym urządzeniu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
my_device = [platform[0].get_devices()[0]] # ta czesc kodu musi byc dostosowana do sprzetu na ktorym sa prowadzone cwiczenia&lt;br /&gt;
ctx = cl.Context(my_gpu_device)&lt;br /&gt;
queue = cl.CommandQueue(ctx, device=my_gpu_device[0]) &lt;br /&gt;
mod = cl.Program(ctx,kernels).build()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Musimy jeszcze przygotować dane. Na początek zdefiniujemy przykładowe dane - pamiętaj przy tym, że obliczenia wykonywać możemy na liczbach pojedynczej precyzji.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
in = np.zeros((300,200,2))&lt;br /&gt;
in[:,:,0] = np.arange((300*200)).reshape((300,200))&lt;br /&gt;
in[:,:,1] = np.arange((300*200)).reshape((300,200)) - 100&lt;br /&gt;
in = in.astype(np.float32) # zmieniamy dane na pojedynczą precyzję&lt;br /&gt;
out = np.zeros((300,200)).astype(np.float32)&lt;br /&gt;
add = np.float32(add)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie zarezerwujemy pamięć, przenosząc od razu dane wejściowe. Poniższe zmienne stanowią rodzaj wskaźnika do interesujących nas miejsc w pamięci urządzenia.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
input = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in)&lt;br /&gt;
output = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=out)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jesteśmy już gotowi do wywołania naszego kernela:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = mod.Sum(queue, (np.int32(300), np.int32(200), 1), (1,1,1), input, output, add)&lt;br /&gt;
# jak widać nasz kernel możemy wywołać jako metodę zmiennej mod. przyjmuje ona na wejściu potok (?) obliczeniowy, całkowite wymiary grup roboczych, wymiary ???? oraz wskaźniki do buforów)&lt;br /&gt;
event.wait()    &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Po wywołaniu kernela pozostaje nam tylko przenieść z powrotem dane wynikowe do pamięci hosta (tak aby były one dostępne do dalszych, standardowych obliczeń z poziomu Pythona).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = cl.enqueue_copy(queue, out, output)&lt;br /&gt;
event.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę sprawdzić dane wynikowe i porównać je z analogicznymi danymi otrzymanymi z obliczeń liniowych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
out_liniowy = in[:,:,0] + in[:,:,1]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę stworzyć kernel, który będzie dostawać dwie tablice liczb zmiennoprzecinkowych, a następnie liczyć sufit (ang. ceil) z wartości bezwzględnych elementów obu tablic i zwracać największy wspólny dzielnik elementów tych tablic. Porównać działanie (wyniki) programu z poniższą liniową implementacją:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Profilowanie==&lt;br /&gt;
Główną przyczyną naszego zainteresowania obliczeniami na GPU jest potencjalny spadek czasu wykonywania wymaganych obliczeń. Z tego punktu widzenia istotna jest możliwość dokładnego określenia czasu obliczeń i porównania algorytmów liniowych z równoległymi. Praktyczny czas trwania obliczeń jest zależny od implementacji sprzętowej, parametrów komputera itp. Nie jest to pojęcie tożsame ze [[wikipedia:Złożoność obliczeniowa | złożonością obliczeniową]].&amp;lt;br&amp;gt;&lt;br /&gt;
Do mierzenia czasu obliczeń liniowych wykorzystamy standardową bibliotekę time. Aby wykonać pojedynczy pomiar czasu działania funkcji y(x) należy wywołać kod poniższej postaci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from time import clock&lt;br /&gt;
start = clock() # wskazanie zegara w danej chwili&lt;br /&gt;
y(x)&lt;br /&gt;
end = clock()&lt;br /&gt;
t=end-start # zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oczywiście, pomiar taki jest obarczony błędem pomiarowym. Z tego względu rozsądne szacunki należy wykonywać w oparciu o dużą liczbę pomiarów. &amp;lt;br&amp;gt;&lt;br /&gt;
Biblioteka time niestety nie współpracuje dobrze z obliczeniami równoległymi - zawyżając wartość efektywnego czasu obliczeń. Z tego względu, OpenCL dostarcza własnych narzędzi do profilowania. Aby możliwe było profilowanie danej kolejki należy deklarując użyć odpowiedniego parametru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
queue=cl.CommandQueue(ctx, device=my_gpu_device[0], properties=cl.command_queue_properties.PROFILING_ENABLE)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aby zmierzyć czas wykonywania naszego kernela Sum z wcześniejszej części tekstu, wykonujemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = mod.Sum(queue, (np.int32(300), np.int32(200), 1), (1,1,1), input, output, add)&lt;br /&gt;
event.wait()&lt;br /&gt;
t = (event.profile.end-event.profile.start)*1e-9 # zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćmy uwagę na to, że wynik dotyczy wyłącznie samych obliczeń - nie uwzględnia on czasu potrzebnego na przeniesienie danych z pamięci hosta do pamięci urządzenia i z pamięci urządzenia do hosta. Czas komunikacji między urządzeniami jest względnie długi - sprawia to, że obliczenia równoległe są opłacalne dopiero przy odpowiednio dużych danych wejściowych. W oparciu o poniższy kod możemy zmierzyć, ile czasu trwa skopiowanie zawartości zmiennej in do bufora input w pamięci urządzenia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
start_event=cl.enqueue_marker(queue)&lt;br /&gt;
input = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in)&lt;br /&gt;
t = (event.profile.end-start_event.profile.start)*1e-9 # zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analogicznie zmierzyć możemy czas potrzebny na przeniesienie wyników z pamięci urządzenia do pamięci hosta.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
#Dla kilku wybranych rozmiarów tablicy danych wejściowych zmierzyć (liczba powtórzeń &amp;gt;10000) czas potrzebny na: &lt;br /&gt;
#* przeniesienie danych z hosta do urządzenia;&lt;br /&gt;
#* wykonanie kernela Sum; &lt;br /&gt;
#* przeniesienie danych z urządzenia do hosta.&lt;br /&gt;
#:Czy czasy te rosną liniowo z rozmiarem tablicy?&lt;br /&gt;
# Zmierzyć (liczba powtórzeń &amp;gt;10000) czas trwania obliczeń funkcji np.add(x,y) dla kilku wybranych rozmiarów tablic danych wejściowych (rozmiary tożsame z rozmiarami z podpunktu pierwszego).&lt;br /&gt;
#:Czy wielkość ta zmienia się liniowo z rozmiarem tablicy?&lt;br /&gt;
# Na podstawie powyższego ocenić: (dla konkretnego komputera) od jakiego rozmiaru tablicy zrównoleglenie obliczeń zaczyna być opłacalne?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/GPU&amp;diff=5525</id>
		<title>USG/GPU</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/GPU&amp;diff=5525"/>
		<updated>2016-07-03T12:27:01Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Wstęp do obliczeń równoległych na GPU=&lt;br /&gt;
W tej części ćwiczeń stworzymy pierwszy program wykorzystujący bibliotekę OpenCL do obliczeń na kartach graficznych. &lt;br /&gt;
Posłużymy się pythonowym wrapperem do OpenCL - biblioteką PyOpencl. Same kernele będziemy pisać w języku C, ale wszystkie dodatkowe procedury będziemy mogli pisać przy użyciu standardowych poleceń Pythona.&lt;br /&gt;
Zaczniemy od stworzenia prostego programu sumującego dwie tablice liczb zmiennoprzecinkowych i następnie mnożącego tę sumę przez pewien ustalony mnożnik.&lt;br /&gt;
Na sam początek importujemy bibliotekę:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
import pyopencl as cl&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Kod OpenCL przechowywać będziemy w postaci zmiennej tekstowej. Stworzymy prosty kernel, który dostaje wejściu dwie tablice o wymiarach odpowiednio &amp;lt;math&amp;gt;N\times M\times 2&amp;lt;/math&amp;gt; i &amp;lt;math&amp;gt;N\times M&amp;lt;/math&amp;gt; oraz zmienną z mnożnikiem. Kernel wykorzystywać będzie &amp;lt;math&amp;gt;N\cdot M&amp;lt;/math&amp;gt; jednostek obliczeniowych. Pierwsza tablica zawiera nasze dane wejściowe (ostatni wymiar koduje indeks tablicy wejściowej); druga tablica będzie tablicą w której przechowywać będziemy wynik obliczeń. Przykładowy kernel zdefiniowany jest poniżej:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
kernels=&amp;quot;&lt;br /&gt;
        __kernel void Sum(__global float *in, __global float *out, const float add)&lt;br /&gt;
        {&lt;br /&gt;
        //zaczynamy od zadeklarowania zmiennych&lt;br /&gt;
        const int n = get_global_id(0); //indeks w pierwszym wymiarze danej jednostki roboczej&lt;br /&gt;
        const int m = get_global_id(1); //indeks w drugim wymiarze danej jednostki roboczej&lt;br /&gt;
        const int M = get_global_size(1); &lt;br /&gt;
        const int nm = n*M + m; // indeks w tablicy wyjsciowej odpowiadajacy wartości o współrzędnych (n,m)&lt;br /&gt;
        __private int index1; // indeks w zmiennej wejsciowej odpowiadajacy wartości o współrzędnych (n,m,0) &lt;br /&gt;
        __private int index2; // indeks w zmiennej wejsciowej odpowiadajacy wartości o współrzędnych (n,m,1) &lt;br /&gt;
        index1 = 0 + m * 2 + n * M  * 2;&lt;br /&gt;
        index2 = 1 + m * 2 + n * M  * 2;&lt;br /&gt;
        out[nm] = (in[index1]+in[index2]) * add;&lt;br /&gt;
        }&lt;br /&gt;
&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu wywołania kernela będziemy musieli przygotować środowisko OpenCL, skompilować kod OpenCL (za pomocą odpowiednich funkcji w Pythonie) oraz zarezerwować miejsce w pamięci i przesłać dane do bufora pamięci na GPU.&lt;br /&gt;
Na początek sprawdzimy jakie procesory mamy do dyspozycji&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
platform = cl.get_platforms()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę wypisać zmienną platform. Zależnie od sprzętu i oprogramowania do dyspozycji będziemy mieli jedną lub więcej platform (gdy np. mamy proces Intela i kartę graficzną AMD) wraz z określoną liczbą urządzeń na każdej platformie. Dostępne urządzenia na pierwszej platformie możemy podejrzeć wywołując:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
print platform[0].get_devices()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wybierzemy jedno z urządzeń i skompilujemy nasz kernel do obliczeń na tym urządzeniu&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
my_device = [platform[0].get_devices()[0]] # ta czesc kodu musi byc dostosowana do sprzetu na ktorym sa prowadzone cwiczenia&lt;br /&gt;
ctx = cl.Context(my_gpu_device)&lt;br /&gt;
queue=cl.CommandQueue(ctx, device=my_gpu_device[0]) &lt;br /&gt;
mod = cl.Program(ctx,kernels).build()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Musimy jeszcze przygotować dane. Na początek zdefiniujemy przykładowe dane - pamiętaj przy tym, że obliczenia wykonywać możemy na liczbach pojedynczej precyzji.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
in=np.zeros((300,200,2))&lt;br /&gt;
in[:,:,0] = np.arange((300*200)).reshape((300,200))&lt;br /&gt;
in[:,:,1] = np.arange((300*200)).reshape((300,200)) - 100&lt;br /&gt;
in = in.astype(np.float32) # zmieniamy dane na pojedynczą precyzję&lt;br /&gt;
out = np.zeros((300,200)).astype(np.float32)&lt;br /&gt;
add = np.float32(add)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie zarezerwujemy pamięć, przenosząc od razu dane wejściowe. Poniższe zmienne stanowią rodzaj wskaźnika do interesujących nas miejsc w pamięci urządzenia.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
input = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in)&lt;br /&gt;
output = cl.Buffer(ctx, mf.READ_WRITE | mf.COPY_HOST_PTR, hostbuf=out)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jesteśmy już gotowi do wywołania naszego kernela:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = mod.Sum(queue, (np.int32(300), np.int32(200), 1), (1,1,1), input, output, add)&lt;br /&gt;
# jak widać nasz kernel możemy wywołać jako metodę zmiennej mod. przyjmuje ona na wejściu potok (?) obliczeniowy, całkowite wymiary grup roboczych, wymiary ???? oraz wskaźniki do buforów)&lt;br /&gt;
event.wait()    &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Po wywołaniu kernela pozostaje nam tylko przenieść z powrotem dane wynikowe do pamięci hosta (tak aby były one dostępne do dalszych, standardowych obliczeń z poziomu Pythona).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = cl.enqueue_copy(queue, out, output)&lt;br /&gt;
event.wait()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Proszę sprawdzić dane wynikowe i porównać je z analogicznymi danymi otrzymanymi z obliczeń liniowych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
out_liniowy = in[:,:,0] + in[:,:,1]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę stworzyć kernel, który będzie dostawać dwie tablice liczb zmiennoprzecinkowych, a następnie liczyć sufit (ang. ceil) z wartości bezwzględnych elementów obu tablic i zwracać największy wspólny dzielnik elementów tych tablic. Porównać działanie (wyniki) programu z poniższą liniową implementacją:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Profilowanie==&lt;br /&gt;
Główną przyczyną naszego zainteresowania obliczeniami na GPU jest potencjalny spadek czasu wykonywania wymaganych obliczeń. Z tego punktu widzenia istotna jest możliwość dokładnego określenia czasu obliczeń i porównania algorytmów liniowych z równoległymi. Praktyczny czas trwania obliczeń jest zależny od implementacji sprzętowej, parametrów komputera itp. Nie jest to pojęcie tożsame ze [[wikipedia:Złożoność obliczeniowa | złożonością obliczeniową]].&amp;lt;br&amp;gt;&lt;br /&gt;
Do mierzenia czasu obliczeń liniowych wykorzystamy standardową bibliotekę time. Aby wykonać pojedynczy pomiar czasu działania funkcji y(x) należy wywołać kod poniższej postaci&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
from time import clock&lt;br /&gt;
start = clock() #wskazanie zegara w danej chwili&lt;br /&gt;
y(x)&lt;br /&gt;
end = clock()&lt;br /&gt;
t=end-start #zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oczywiście, pomiar taki jest obarczony błędem pomiarowym. Z tego względu rozsądne szacunki należy wykonywać w oparciu o dużą liczbę pomiarów. &amp;lt;br&amp;gt;&lt;br /&gt;
Biblioteka time niestety nie współpracuje dobrze z obliczeniami równoległymi - zawyżając wartość efektywnego czasu obliczeń. Z tego względu, OpenCL dostarcza własnych narzędzi do profilowania. Aby możliwe było profilowanie danej kolejki należy deklarując użyć odpowiedniego parametru:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
queue=cl.CommandQueue(ctx, device=my_gpu_device[0],properties=cl.command_queue_properties.PROFILING_ENABLE)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aby zmierzyć czas wykonywania naszego kernela Sum z wcześniejszej części tekstu, wykonujemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
event = mod.Sum(queue, (np.int32(300), np.int32(200), 1), (1,1,1), input, output, add)&lt;br /&gt;
event.wait()&lt;br /&gt;
t=(event.profile.end-event.profile.start)*1e-9 #zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zwróćmy uwagę na to, że wynik dotyczy wyłącznie samych obliczeń - nie uwzględnia on czasu potrzebnego na przeniesienie danych z pamięci hosta do pamięci urządzenia i z pamięci urządzenia do hosta. Czas komunikacji między urządzeniami jest względnie długi - sprawia to, że obliczenia równoległe są opłacalne dopiero przy odpowiednio dużych danych wejściowych. W oparciu o poniższy kod możemy zmierzyć, ile czasu trwa skopiowanie zawartości zmiennej in do bufora input w pamięci urządzenia:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
start_event=cl.enqueue_marker(queue)&lt;br /&gt;
input = cl.Buffer(ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=in)&lt;br /&gt;
t=(event.profile.end-start_event.profile.start)*1e-9 #zmierzony czas&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Analogicznie zmierzyć możemy czas potrzebny na przeniesienie wyników z pamięci urządzenia do pamięci hosta.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
#Dla kilku wybranych rozmiarów tablicy danych wejściowych zmierzyć (liczba powtórzeń &amp;gt;10000) czas potrzebny na: &lt;br /&gt;
#* przeniesienie danych z hosta do urządzenia;&lt;br /&gt;
#* wykonanie kernela Sum; &lt;br /&gt;
#* przeniesienie danych z urządzenia do hosta.&lt;br /&gt;
#:Czy czasy te rosną liniowo z rozmiarem tablicy?&lt;br /&gt;
# Zmierzyć (liczba powtórzeń &amp;gt;10000) czas trwania obliczeń funkcji np.add(x,y) dla kilku wybranych rozmiarów tablic danych wejściowych (rozmiary tożsame z rozmiarami z podpunktu pierwszego).&lt;br /&gt;
#:Czy wielkość ta zmienia się liniowo z rozmiarem tablicy?&lt;br /&gt;
# Na podstawie powyższego ocenić: (dla konkretnego komputera) od jakiego rozmiaru tablicy zrównoleglenie obliczeń zaczyna być opłacalne?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=5524</id>
		<title>USG/Projekty</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Projekty&amp;diff=5524"/>
		<updated>2016-07-03T12:24:37Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Short-lag Spatial Coherence==&lt;br /&gt;
Short-lag Spatial Coherence (SLSC) jest alternatywną metodą obrazowania tkanek, względem klasycznej prezentacji B-Mode. W odróżnieniu od standardowego podejścia, obraz nie przedstawia energii z rozproszenia, a stopień koherencji (spójności) przestrzennej pomiędzy sygnałami rejestrowanymi przez różne przetworniki odbiorcze. Projekt polegać będzie na zaimplementowaniu prostego toru obliczania obrazu SLSC z danych RF na podstawie pracy &amp;lt;ref&amp;gt;Lediju, Muyinatu A., et al. &amp;quot;Short-lag spatial coherence of backscattered echoes: Imaging characteristics.&amp;quot; IEEE transactions on ultrasonics, ferroelectrics, and frequency control 58.7 (2011): 1377-1388.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Obrazowanie tłumienia==&lt;br /&gt;
Na zajęciach badane było przesunięcie pasma częstotliwości sygnału odebranego względem sygnału nadanego powstałe w wyniku efektu Dopplera. Pewne przesunięcie widma obserwuje się jednak również dla obiektów statycznych i jest ono zależne od współczynnika tłumienia tkanki obrazowej. Efekt ten pozwala potencjalnie na tworzenie mapy współczynnika tłumienia i w konsekwencji - uzyskanie dodatkowej informacji na temat obrazowanej tkanki. Projekt polegać będzie na zaimplementowaniu jednej z metod tworzenia takiej mapy w oparciu o estymator częstotliwości średniej.&lt;br /&gt;
&lt;br /&gt;
==Metody estymacji średniej częstości dopplerowskiej==&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Parametryczne&amp;diff=5523</id>
		<title>USG/Parametryczne</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Parametryczne&amp;diff=5523"/>
		<updated>2016-07-03T12:22:06Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Obrazowanie parametryczne=&lt;br /&gt;
Jednym z istotnym problemów badawczych w ultrasonografii jest zagadnienie estymacji prędkości dźwięku w obrazowanej strukturze. Informacja taka może być wykorzystana zarówno do lepszego obrazowania (minimalizacja błędów rekonstrukcji), jak i potencjalnie do charakteryzowania różnych rodzajów tkanek.&lt;br /&gt;
&lt;br /&gt;
Standardowo, rekonstruując obraz RFów przyjmujemy stałą średnią prędkość dźwięku na całej głębokości pomiarowej (1540m/s). W rzeczywistości prędkość w różnych rodzajach tkanek miękkich jest różna (od 1450m/s dla tłuszczu do 1570m/s dla krwi). Jednocześnie, charakterystyka odbiciowa struktur o różnej prędkości dźwięku może być nieodróżnialna na prezentacji B-mode. &amp;lt;br&amp;gt;&lt;br /&gt;
Celem tych ćwiczeń będzie implementacja prostej metody szacującej pośrednio różnicę między założoną prędkością dźwięku, a faktyczną prędkością dźwięku.&lt;br /&gt;
&lt;br /&gt;
==Metoda==&lt;br /&gt;
Wiele metod estymujących prędkość korzysta z możliwości nadawania fal o różnym froncie falowym. Rozważmy obrazowanie falą płaską pod dwoma kątami, np. -10 i 10 stopni. Mając zrekonstruowane oba obrazy możemy policzyć wzajemną korelację pomiędzy obrazami (przy oknach ustalonej długości), tworząc mapę korelacji. Zauważmy, że dopóki przyjęta do rekonstrukcji prędkość dźwięku jest bliska rzeczywistej, obrazy z obu kątów powinny być mocno skorelowane. Pojawienie się dużej różnicy między tymi prędkościami spowoduje &amp;quot;rozjechanie&amp;quot; się sygnałów z różnych kątów. W konsekwencji, zmaleje korelacja między sygnałami. &amp;lt;br&amp;gt;&lt;br /&gt;
W praktyce, taki obraz korelacji nie jest jeszcze obrazem prędkości dźwięku - jest to tylko pośrednia informacja na temat rozkładu takich prędkości, którą można byłoby następnie wykorzystać do rozwiązania odpowiedniego problemu odwrotnego. W praktyce jednak już sam taki obraz może dostarczyć istotnej informacji diagnostycznej.&lt;br /&gt;
&lt;br /&gt;
Do dyspozycji mamy [http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg4_1480ms.npy plik z danymi] z fantomu z inkluzją o prędkości dźwięku różnej od prędkości dźwięku otoczenia. Tradycyjnie, parametry: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # odległość między środkami kolejnych przetworników [m]&lt;br /&gt;
&lt;br /&gt;
na = 15 # Liczba nadań&lt;br /&gt;
theta = [-10,0,10] # kąty dla kolejnych nadań ?????&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników w pełnej aperturze&lt;br /&gt;
Ntr = 192 # Pełna subapertura nadawcza&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Surowe dane RF znajdują się w tablicy o wymiarach &amp;lt;math&amp;gt;NT\times N \times na &amp;lt;/math&amp;gt; &amp;lt;br&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji (maksymalnej głębokości obrazowanej) danych z pojedynczego nadania.&lt;br /&gt;
&lt;br /&gt;
==Zadania==&lt;br /&gt;
#Zaimplementować procedurę liczącą mapę współczynników korelacji w oknie głębokości pomiędzy obrazami. &lt;br /&gt;
#Zbadać taką mapę dla zrekonstruowanych danych z zadania, dla różnych kątów. Jak dobór kątów i ich liczby wpływa na wynikową tablicę?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5522</id>
		<title>USG/PWI</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/PWI&amp;diff=5522"/>
		<updated>2016-07-03T12:20:15Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Obrazowanie falą płaską==&lt;br /&gt;
W obrazowaniu fala płaską (ang. PWI - Plane Wave Imaging) wektor opóźnień nadawczych ma postać prostej, co pozwala uformować wiązkę o płaskim froncie falowym. W odróżnieniu do rozważanej wcześniej metody klasycznego beamformingu, wiązka taka jest nieogniskowana. O froncie falowym w PWI możemy myśleć jak o froncie fali pochodzącej ze źródła punktowego (ognisko wirtualne) położonego względnie daleko za aperturą (w tym sensie, że różnice w czasach przejścia od ogniska wirtualnego do różnych przetworników nadawczych są pomijalne).&amp;lt;br&amp;gt;&lt;br /&gt;
O ile nie ograniczają nas możliwości techniczne sprzętu (np. mała moc obliczeniowa), w PWI staramy się nadawać i odbierać pełną aperturą. Punktem wyjścia jest fala płaska nadawana pod kątem zerowym względem apertury. Takiemu schematowi nadawczemu odpowiada wektor opóźnień określony funkcją stałą (wszystkie przetworniki nadają w tym samym momencie). Obrót wykresu opóźnień nadawczych odpowiada zmianie kąta nadawczego.&lt;br /&gt;
[[Plik:Rys_falaplaska.png|200px|thumb|right|Schemat ilustrujący nadanie falą płaską pod kątami: a) zerowym i b)niezerowym]]&lt;br /&gt;
Do stworzenia obrazu ultradźwiękowego wystarczą nam dane zebrane dla pojedynczego nadania (z jednego kąta). W praktyce jednak wykonuje się kilka pomiarów (nadań, strzałów itp.) dla kilku rożnych kątów - pozwala to uzyskać poprawę zarówno rozdzielczości punktowej obrazu, jak i poprawę kontrastu i zwiększenie stosunku sygnału do szumu (SNR - Signal-to-Noise Ratio). &lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
na = 3 # Liczba nadań&lt;br /&gt;
theta = [-10,0,10] # kąty dla kolejnych nadań&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników w pełnej aperturze&lt;br /&gt;
Ntr = 192 # Pełna subapertura nadawcza&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Surowe dane RF===&lt;br /&gt;
Do dyspozycji mamy ponownie dwa pliki z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_nitki.npy usg2_nitki.npy]) i cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg2_pwi_cysty.npy usg2_cysty.npy]). W każdym pliku znajduje się trójwymiarowa tablica &amp;lt;math&amp;gt;NT\times N \times na &amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji (maksymalnej głębokości obrazowanej) danych z pojedynczego nadania. &amp;lt;br&amp;gt;&lt;br /&gt;
Kluczowe dla dalszych obliczeń będzie wyznaczenie chwili zerowej, czyli momentu rozpoczęcia akwizycji danych. Na różnych urządzeniach przyjmowane są różne konwencje - czasami akwizycja danych rozpoczyna się w momencie, gdy rozpoczyna się nadawanie; czasami akwizycja rozpoczyna się jeszcze przed nadawaniem. &amp;lt;br&amp;gt;&lt;br /&gt;
Zadanie: proszę wyświetlić surowe dane RF (funkcja plot) dla kilku kolejnych nadań i spróbować określić (w przybliżeniu) w jakim momencie rozpoczyna się akwizycja danych:&lt;br /&gt;
a) przed rozpoczęciem nadawania&lt;br /&gt;
b) w momencie rozpoczęcia nadawania&lt;br /&gt;
c) w chwili gdy nadała połowa przetworników&lt;br /&gt;
&lt;br /&gt;
===Rekonstrukcja obrazu z pojedynczego strzału===&lt;br /&gt;
W przypadku klasycznej rekonstrukcji dokonywaliśmy najpierw przesunięcia w czasie próbek RF, a następnie przesunięty (syntezowany) obraz interpolowaliśmy do siatki odpowiadającej rzeczywistym proporcjom obrazowanej struktury. W przypadku PWI wygodniej będzie nam najpierw określić siatkę, a następnie dla kolejnych punktów na tej siatce liczyć wartość pikseli.&lt;br /&gt;
Poniższy kod wygeneruje dwie tablice, w których przechowywane są współrzędne poziome i pionowe w [m] kolejnych punktów siatki. Siatka jest generowana przy założeniu, że punkt (0,0) znajduje się w środku apertury. Przyjmuje się, że aby otrzymać optymalną jakość obrazowania na jedną długość fali powinny przypadać przynajmniej cztery próbki obrazu (por. Smith 1966, rozdział 11).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
halfWidth = 0.02 # Połowa szerokości obrazowania [m] &lt;br /&gt;
lmbda = c/fs&lt;br /&gt;
step=lmbda/4.&lt;br /&gt;
maxdepth = N*c/(fs*2) # maksymalna głębokość [m]&lt;br /&gt;
mindepth = 0.005 # minimalna głębokość [m]&lt;br /&gt;
&lt;br /&gt;
X0 = np.arange(-halfWidth,halfWidth,ar)&lt;br /&gt;
R0 = np.arange(mindepth,maxdepth,br)&lt;br /&gt;
Grid_div_x,Grid_div_z = np.meshgrid(X0,R0,indexing='xy') # tablice ze współrzędnymi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Podobnie jak wcześniej sygnał w punkcie (x,y) będziemy liczyć jako sumę sygnałów z każdego przetwornika odbiorczego odpowiednio opóźnionych:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S(x,y)=\sum^{NT-1}_{k=0} s_k(t_{tr}(x,y)+t_k(x,y)) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_k(i)&amp;lt;/math&amp;gt; to sygnał z danego przetwornika odbiorczego; &amp;lt;math&amp;gt;t_{tr}(x,y)&amp;lt;/math&amp;gt; czas przejścia fali do punktu obrazowania; &amp;lt;math&amp;gt;t_k(x,y)&amp;lt;/math&amp;gt; czas przejścia fali odbitej z punktu do przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;.&amp;lt;br&amp;gt;&lt;br /&gt;
Dla ustalonego przetwornika &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt; i punktu (x,y) opóźnienie liczone jest jako czas przejścia fali od początku nadania do punktu i z powrotem do danego przetwornika odbiorczego. &lt;br /&gt;
W przypadku PWI możemy założyć, że dla kąta nadawczego &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;t_{tr}(x,y) = (x\cdot sin(\theta)+y\cdot cos(\theta))/c + t_{start} + d &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;d&amp;lt;/math&amp;gt; jest pewnym przesunięciem stałym dla danego nadania - wyznaczonym przez położenie chwili zerowej (moment rozpoczęcia akwizycji). &lt;br /&gt;
&lt;br /&gt;
Do wykonania&lt;br /&gt;
# Stworzyć funkcję, która dla zadanej siatki obliczać będzie wartości energii dla pojedynczego strzału z danego kąta. Podobnie jak wcześniej, interesuje nas obraz w skali decybelowej z ograniczoną dynamiką.&lt;br /&gt;
# Porównać obraz syntezowany dla zadanej wcześniej siatki z obrazem syntezowanym dla siatki o dwukrotnie większych odległościach między punktami&lt;br /&gt;
&lt;br /&gt;
===Apodyzacja po stronie odbiorczej===&lt;br /&gt;
Standardową metodą poprawy jakości obrazu jest zastosowanie apodyzacji po stronie odbiorczej. W czasie rekonstrukcji natężenie w danym punkcie liczyliśmy jako sumę sygnałów z pojedynczych przetworników odbiorczych. Sygnały z pojedynczych przetworników zawierają jednak informację pochodzącą nie tylko z rozproszenia w danym punkcie. Ponadto, dla dwóch różnych przetworników odbiorczych energia sygnału pochodząca z rozproszenia z danego punktu niekoniecznie musi stanowić taką samą cześć całkowitej energii sygnału. W celu zbadania tego zjawiska:&lt;br /&gt;
# Stworzyć funkcję, która dla zadanego punktu liczy sygnał jako sumę sygnałów tylko z wybranej części przetworników odbiorczych (np. wybranych 12 przetworników). Proszę porównać otrzymane obrazy dla kilku wybranych subapertur odbiorczych (np. pierwsze 12 przetworników, środkowe 12 przetworników i ostatnie 12 przetworników - licząc od lewego końca apertury). Jak bardzo różnią się te obrazy między sobą i jak różnią się od obrazu otrzymanego z pełnej apertury odbiorczej? &lt;br /&gt;
&lt;br /&gt;
Możemy zauważyć, że więcej informacji o danym punkcie zawierają przetworniki położone bliżej tego punktu niż przetworniki położone dalej. Apodyzacja po stronie odbiorczej polega na zastosowaniu przy rekonstrukcji wag, które będą odpowiednio proporcjonalne do odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
# Proszę zaimplementować zmodyfikowany algorytm rekonstrukcji wykorzystujący jakąś wybraną formę apodyzacji odbiorczej, gdzie sumowane sygnały z pojedynczych przetworników odbiorczych będą ważone wartościami niemalejącej funkcji od odległości przetwornika od punktu pomiarowego.&lt;br /&gt;
&lt;br /&gt;
===Złożenie (compounding) obrazów z nadań pod różnymi kątami===&lt;br /&gt;
Jednym z prostych sposobów poprawienia obrazu jest złożenie ze sobą (np. przez średnią arytmetyczną) kilku obrazów z różnych kątów nadawczych.&lt;br /&gt;
&lt;br /&gt;
# Zaimplementować procedurę uśredniającą obrazy otrzymane z kilku kątów nadawczych. &lt;br /&gt;
# Zbadać obraz zrekonstruowany dla wybranego niezerowego kąta nadawczego i spróbować odpowiedzieć na pytanie: czy dla wszystkich punktów na siatce rekonstrukcja jest sensowna? Czy są punkty, które należałoby pominąć w procesie rekonstrukcji/sumowania przy składaniu obrazów z wielu kątów?&lt;br /&gt;
&lt;br /&gt;
===Literatura===&lt;br /&gt;
#Tanter, Mickael, and Mathias Fink. &amp;quot;Ultrafast imaging in biomedical ultrasound.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 61.1 (2014): 102-119.&lt;br /&gt;
#Cikes, Maja, et al. &amp;quot;Ultrafast cardiac ultrasound imaging: Technical principles, applications, and clinical benefits.&amp;quot; JACC: Cardiovascular Imaging 7.8 (2014): 812-823.&lt;br /&gt;
#Montaldo, Gabriel, et al. &amp;quot;Coherent plane-wave compounding for very high frame rate ultrasonography and transient elastography.&amp;quot; Ultrasonics, Ferroelectrics, and Frequency Control, IEEE Transactions on 56.3 (2009): 489-506.&lt;br /&gt;
#Smith, Warren J. Modern optical engineering. Tata McGraw-Hill Education, 1966.&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5521</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5521"/>
		<updated>2016-07-03T12:16:59Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|thumb|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|thumb|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
# wybieramy indeksy którym odpowiadają niezerowe wartości&lt;br /&gt;
# - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
indices = indices + indices2&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5520</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5520"/>
		<updated>2016-07-03T12:15:40Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|thumb|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|thumb|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości&lt;br /&gt;
                               - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5519</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5519"/>
		<updated>2016-07-03T12:14:39Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|thumb|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|thumb|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5518</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5518"/>
		<updated>2016-07-03T12:13:55Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|frame|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|frame|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5517</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5517"/>
		<updated>2016-07-03T12:12:13Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|frame|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|frame|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5516</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5516"/>
		<updated>2016-07-03T12:07:49Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|thumb|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|thumb|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5515</id>
		<title>USG/Klasyczna rekonstrukcja</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Klasyczna_rekonstrukcja&amp;diff=5515"/>
		<updated>2016-07-03T12:06:06Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Klasyczna rekonstrukcja obrazu (Beamforming)=&lt;br /&gt;
Schemat nadawczy jest następujący.&lt;br /&gt;
[[Plik:Rys_przetworniki_nadawanie.png|200px|thumb|right|Wielkości odpowiadające wymiarom tablicy z danymi]]&lt;br /&gt;
W każdym nadaniu przetworniki subapertury nadawczej generują wiązkę o stałym ognisku. Subaperturę nadawczą w &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tym nadaniu tworzą przetworniki od &amp;lt;math&amp;gt;n&amp;lt;/math&amp;gt;-tego do &amp;lt;math&amp;gt;(n+N_{tr})&amp;lt;/math&amp;gt;-tego (gdzie &amp;lt;math&amp;gt;N_{tr}&amp;lt;/math&amp;gt; - to liczba przetworników subapertury nadawczej). Zakładamy, że ognisko położone jest na osi centralnej subapertury nadawczej. Kształt wiązki otrzymujemy przez zastosowanie odpowiednich opóźnień nadawczych pomiędzy przetwornikami. Od momentu nadania wszystkie przetworniki (pełna apertura odbiorcza) rejestrują sygnał. Rejestracja sygnału trwa do &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;-tego okresu częstotliwości próbkowania - wielkość ta odpowiada maksymalnej głębokości obrazowania &amp;lt;math&amp;gt;D&amp;lt;/math&amp;gt; w przybliżeniu zgodnie ze wzorem:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;D=\frac{N\cdot c}{2f_{s}} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;f_{s}&amp;lt;/math&amp;gt; - częstotliwość próbkowania; &amp;lt;math&amp;gt;c&amp;lt;/math&amp;gt; - średnia prędkość dźwięku w ośrodku. &amp;lt;br&amp;gt;&lt;br /&gt;
Subapertura nadawcza przesuwana jest w kolejnych emisjach o 1 przetwornik.&lt;br /&gt;
&lt;br /&gt;
Parametry potrzebne do dalszej pracy: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 5.5e6 # Częstotliwość nadawcza przetworników [Hz]&lt;br /&gt;
fs = 50e6 # Częstotliwość próbkowania [Hz]&lt;br /&gt;
pitch = 0.21e-3 # Deklarowana odległość między środkami przetworników nadawczo-odbiorczych (tzw. pitch) [m]&lt;br /&gt;
&lt;br /&gt;
NT = 192 # Liczba przetworników głowicy (pełna apertura)&lt;br /&gt;
Ntr = 64 # Liczba przetworników aktywnej subapertury&lt;br /&gt;
&lt;br /&gt;
Rf1 = 40e-3 # Położenie ogniska wiązki nadawczej od środka subapertury nadawczej [m]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ponadto, do rekonstrukcji wykorzystywać będziemy prędkość dźwięku w ośrodku. Zakładamy, że jest ona stała. Rekonstrukcję przeprowadzać będziemy dla danych z eksperymentów in vitro na dwóch fantomach - nitkowym oraz cystowym. Fantom nitkowy składa się z matrycy żyłek położonych w równych od odstępach, które umieszczone są następnie w zbiorniku wodnym. Płaszczyzna obrazowania przecina żyłki prostopadle, w efekcie czego na obrazie ultradźwiękowym każdej nitce odpowiadać powinien obiekt punktowy o jasności większej od jasności tła. &amp;lt;br&amp;gt;&lt;br /&gt;
Fantom cystowy składa się z materiału o właściwościach akustycznych (prędkość dźwięku w ośrodku, tłumienie itp.) zbliżonych do tkanki ludzkiej; w materiale tym umieszczone są cysty. Cysty te widoczne będą na obrazie ultradźwiękowym jako owalne obiekty o jasności mniejszej od jasności tła (cysta rozprasza mniej niż tło).&lt;br /&gt;
[[Plik:Rys_fantom_cystowy.png|200px|thumb|right|Zdjęcie fantomu cystowego wraz ze schematem obrazującym przekrój fantomu w przybliżeniu odpowiadający płaszczyźnie obrazowania]] &lt;br /&gt;
[[Plik:Rys_fantom_nitkowy.png|200px|thumb|right|Zdjęcie fantomu nitkowego z góry. Płaszczyzna obrazowania jest umiejscowiona w przybliżeniu prostopadle do kierunku nitek. Dane zebrane były dla fantomu położonego w zbiorniku wody.]]  Dla pomiarów w fantomie cystowym proszę założyć:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1540 # [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
zaś dla pomiarów w fantomie nitkowym&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
c = 1490 # prędkość dźwięku w wodzie destylowanej [m/s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Będziemy korzystać z bibliotek:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
import numpy as np&lt;br /&gt;
import pylab as py&lt;br /&gt;
import scipy.signal as sig&lt;br /&gt;
from PIL import ImageTk, Image&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Dane RF==&lt;br /&gt;
Do dyspozycji mamy dwa zestawy danych RF z pomiarów na fantomie nitkowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_cysty.npy plik usg1_nitki.npy]) i na fantomie cystowym ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg1_sta_nitki.npy plik usg1_cysty.npy]).&lt;br /&gt;
Zaczniemy od wczytania oraz wyświetlenia (funkcja plot) surowych danych RF (przed rekonstrukcją obrazu). Dane możemy wczytać za pomocą poleceń&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
RF=np.load('usg1_nitki.npy')&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dostaliśmy tablicę o wymiarach &amp;lt;math&amp;gt;NT\times N \times (NT-N_{tr}) &amp;lt;/math&amp;gt; gdzie &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; odpowiada czasowi rejestracji danych z pojedynczego nadania.&lt;br /&gt;
Proszę podejrzeć dane zebrane dla kilku strzałów (np. pierwszego i ostatniego). Dla przejrzystości proszę podejrzeć jedynie pierwsze 300 próbek:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
py.subplot(2, 1, 1)&lt;br /&gt;
py.imshow(RF[:, :300, 0]&lt;br /&gt;
py.subplot(2, 1, 2)&lt;br /&gt;
py.imshow(RF[:, :300, -1]&lt;br /&gt;
py.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmieniają się sygnały między kolejnymi strzałami? &lt;br /&gt;
Czy na podstawie samych surowych danych widoczna jest oczekiwana struktura (obrazowane obiekty)?&lt;br /&gt;
Jak zmienia się energia sygnałów dla różnych przetworników odbiorczych zależnie od odległości od środka subapertury?&lt;br /&gt;
&lt;br /&gt;
==Opóźnienia nadawczo-odbiorcze==&lt;br /&gt;
Z danych zebranych dla pojedynczego nadania rekonstruować będziemy pojedynczą linię obrazu. Wykorzystamy do tego sygnału z tych samych przetworników, które nadawały (subapertura odbiorcza). Wartość sygnału pojedynczego piksela otrzymamy sumując sygnały z tych przetworników przesunięte zgodnie z określonymi opóźnieniami odbiorczymi. Sygnał &amp;lt;math&amp;gt;S_{(i,j)}&amp;lt;/math&amp;gt; dla piksela w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tej linii i głębokości &amp;lt;math&amp;gt;j&amp;lt;/math&amp;gt; otrzymujemy jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;S_{(i,j)}=\sum^{N_{tr}-1}_{k=0} s_{i,k}(j+t_{i}(k)))&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;s_{i,k}(t)&amp;lt;/math&amp;gt; - sygnał z &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tego nadania i &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w chwili &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt;;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;t_{i}(k)&amp;lt;/math&amp;gt; - opóźnienie nadawczo-odbiorcze &amp;lt;math&amp;gt;k&amp;lt;/math&amp;gt;-tego przetwornika w &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;-tym nadaniu.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W klasycznej metodzie beamformingu do rekonstrukcji wykorzystujemy takie same opóźnienia jak te użyte przy nadawaniu. Funkcja powinna dla zadanej liczby przetworników i odległości ogniska położonego w punkcie &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt; generować tablicę opóźnień, gdzie opóźnienie dla przetwornika położonego w punkcie &amp;lt;math&amp;gt;(a,b)&amp;lt;/math&amp;gt; określone jest jako&lt;br /&gt;
&amp;lt;math&amp;gt;\sqrt{(x-a)^2+(y-b)^2}/c &amp;lt;/math&amp;gt;&lt;br /&gt;
Proszę pamiętać, że opóźnienia w powyższym wzorze są podane w sekundach - podczas gdy do dalszych obliczeń wygodniejsze może okazać się wykorzystanie wartości liczonych w okresach próbkowania.&lt;br /&gt;
&lt;br /&gt;
==Rekonstrukcja obrazu==&lt;br /&gt;
[[Plik:schemat_rekonstrukcji.png|200px|thumb|right|Schemat blokowy tworzenia obrazu]] &lt;br /&gt;
Mając już do dyspozycji opóźnienia nadawcze dla interesującego nas punktu ogniskowania możemy przystąpić do rekonstrukcji obrazu. Proszę napisać skrypt dokonujący w pętli rekonstrukcji kolejnych linii obrazu.&lt;br /&gt;
&lt;br /&gt;
Zrekonstruowany obraz przedstawiamy w skali decybelowej. Można wykonać to np. przy użyciu przykładowego kodu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
#tablica img przechowuje zrekonstruowany obraz&lt;br /&gt;
indices = img&amp;gt;0&lt;br /&gt;
indices2 = img&amp;lt;0&lt;br /&gt;
indices = indices + indices2 # wybieramy indeksy którym odpowiadają niezerowe wartości - w przeciwnym wypadku operacja logarytmowania byłaby niejednoznaczna&lt;br /&gt;
img = np.abs(img)/np.max(np.abs(img[indices]))&lt;br /&gt;
img[indices] = 10*np.log(img[indices])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zakres dynamiki===&lt;br /&gt;
Istotny wpływ na wygląd ostatecznego obrazu ma dobór zakresu dynamiki wyświetlanych wartości. Na początek proszę wyświetlić obraz w pełnej dynamice. &amp;lt;br&amp;gt;&lt;br /&gt;
Do wyświetlenia obrazu wykorzystamy bibliotekę PIL, która pozwala nam na łatwe interpolowanie obrazu (przeskalowanie osi). Zwróćmy uwagę, że w naszym schemacie bezpośrednio po rekonstrukcji mamy obraz z zaburzonymi proporcjami - częstotliwość w głębokości związana jest z częstotliwością próbkowania, zaś częstotliwość w szerokości związana jest z odległością między przetwornikami (pitch).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.Greys(img.transpose())*255))&lt;br /&gt;
width = NT*pitch&lt;br /&gt;
depth = N*c/fs&lt;br /&gt;
Frame = Frame.resize((int(N*width/depth)*2, N), Image.BICUBIC)&lt;br /&gt;
Frame.show()&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Następnie proszę rozważyć ograniczenie dynamiki obrazu np. 60dB (zakres od -60dB do 0). Ograniczenie dynamiki jest równoważne z zastosowaniem funkcji progowej&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
indices = img &amp;lt;-low&lt;br /&gt;
img[indices] = -low&lt;br /&gt;
indices = img &amp;gt;= 0&lt;br /&gt;
img[indices] = 0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Czy na obrazach widoczna jest oczekiwana struktura? Jak zakres dynamiki wpływa na obraz?&lt;br /&gt;
&lt;br /&gt;
===Filtrowanie obrazu===&lt;br /&gt;
Aby otrzymać czytelny obraz często niezbędne jest przefiltrowanie obrazu. Proszę wykonać filtrowanie dolno- i górnoprzepustowe obrazu wzdłuż głębokości, np. według poleceń:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
b, a = sig.butter(10, 0.2, 'highpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
b, a = sig.butter(10, 0.9, 'lowpass')    &lt;br /&gt;
img = sig.filtfilt(b, a, img,axis=1)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jak zmienił się obraz po zastosowaniu filtrów? Proszę zbadać jak parametry filtra wpływają na końcowy obraz.&lt;br /&gt;
&lt;br /&gt;
==Obraz B-mode==&lt;br /&gt;
Uzyskanie wynikowego obrazu B-mode (ang. Brightness) ze zrekonstruowanego obrazu RF polega na wyznaczeniu obwiedni sygnałów RF.&lt;br /&gt;
Typowo do jej wyznaczenia stosuje się transformację Hilberta. Przykładowy skrypt zamieniający każdą linię obrazu na jej obwiednię&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
for p in range(np.shape(RF)[2]):&lt;br /&gt;
    img[p, :] = np.abs(sig.hilbert(img[p, :]))&lt;br /&gt;
&amp;lt;/source&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Proszę porównać obraz RF po rekonstrukcji oraz obraz B-mode. Czym się one różnią? Czy informacja utracona w czasie przejścia do obwiedni mogła być istotna z punktu widzenia obrazowania medycznego?&lt;br /&gt;
&lt;br /&gt;
==Położenie ogniska==&lt;br /&gt;
W czasie rekonstrukcji założyliśmy, że ognisko wiązki nadawczej położone było zawsze w określonej odległości od środka subapertury nadawczej. Proszę zbadać:&lt;br /&gt;
# Jak zmienia się ostrość obrazu w zależności od głębokości? Na jakiej głębokości rozdzielczość obrazu wydaje się być najlepsza?&lt;br /&gt;
# Proszę zrekonstruować obraz ponownie zakładając inną odległość ogniska nadawczego (np. dwa razy mniejszą). Jak zmienił się obraz?&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=5514</id>
		<title>USG</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG&amp;diff=5514"/>
		<updated>2016-07-03T12:02:25Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Pracownia USG=&lt;br /&gt;
&lt;br /&gt;
===Wstępna konfiguracja===&lt;br /&gt;
Ćwiczenia przygotowane zostały pod język python. Korzystać będziemy z bibliotek: &lt;br /&gt;
#numpy &lt;br /&gt;
#scipy&lt;br /&gt;
#PIL http://www.pythonware.com/products/pil/&lt;br /&gt;
#PyOpenCL&lt;br /&gt;
&lt;br /&gt;
Ponadto, konieczne jest zainstalowanie SDK OpenCL i sterowników dla posiadanych procesorów lub kart graficznych (np. Intel, AMD, Nvidia) oraz kompilatora (przy pracy na Windowsie prostym rozwiązaniem może być zainstalowanie darmowej wersji Visual Studio &amp;lt;ref&amp;gt;https://www.visualstudio.com/pl-pl/visual-studio-homepage-vs.aspx&amp;lt;/ref&amp;gt;). Zaleca się zainstalowanie w pierwszej kolejności kompilatora oraz SDK OpenCL, a dopiero następnie instalowanie biblioteki PyOpenCL do Pythona.&lt;br /&gt;
&lt;br /&gt;
==Ćwiczenia==&lt;br /&gt;
&lt;br /&gt;
#[[USG/Klasyczna_rekonstrukcja|Klasyczna rekonstrukcja obrazu]]&lt;br /&gt;
#[[USG/PWI|Obrazowanie falą płaską i rozbieżną]]&lt;br /&gt;
#[[USG/Doppler|Obrazowanie prędkości metodą dopplerowską]]&lt;br /&gt;
#[[USG/Parametryczne|Obrazowanie prędkości dźwięku]]&lt;br /&gt;
#[[USG/GPU|Wstęp do obliczeń równoległych na GPU]]&lt;br /&gt;
&lt;br /&gt;
==Projekty zaliczeniowe==&lt;br /&gt;
#[[USG/Projekty|Propozycje tematów zaliczeniowych]]&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5513</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5513"/>
		<updated>2016-07-03T11:58:05Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdej próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). Dla naszych danych wystarczający powinien być filtr o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację z pewnej objętości pomiarowej, co wynika z kształtu wiązki ultradźwiękowej).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego sygnału zespolonego.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
# flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie.&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji).&lt;br /&gt;
&lt;br /&gt;
----&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5512</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5512"/>
		<updated>2016-07-03T11:57:03Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdej próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). Dla naszych danych wystarczający powinien być filtr o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację z pewnej objętości pomiarowej, co wynika z kształtu wiązki ultradźwiękowej).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego sygnału zespolonego.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
# BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
# flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie.&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/hr&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5511</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5511"/>
		<updated>2016-07-03T11:35:47Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego sygnału zespolonego.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
# BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
# flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie.&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji).&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5510</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5510"/>
		<updated>2016-07-03T11:32:38Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego sygnału zespolonego.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
# BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
# flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie.&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji).&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5509</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5509"/>
		<updated>2016-07-03T11:27:11Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5508</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5508"/>
		<updated>2016-07-03T11:25:34Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt; oraz &amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5507</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5507"/>
		<updated>2016-07-03T11:24:30Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
i stąd&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oraz &lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt; R(0)=A(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5506</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5506"/>
		<updated>2016-07-03T11:22:24Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału &amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
oraz&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&amp;lt;math&amp;gt;\dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
i stąd&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
oraz &lt;br /&gt;
&amp;lt;math&amp;gt;R(0)=A(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5505</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5505"/>
		<updated>2016-07-03T11:20:36Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;.&lt;br /&gt;
Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako:&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
Różniczkując powyższe dostajemy:&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
oraz&lt;br /&gt;
&amp;lt;math&amp;gt; \ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;.&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako&lt;br /&gt;
&amp;lt;math&amp;gt; \bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&amp;lt;math&amp;gt; R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;,&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy&lt;br /&gt;
&amp;lt;math&amp;gt;\dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&lt;br /&gt;
i stąd&lt;br /&gt;
&amp;lt;math&amp;gt; \dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
oraz &lt;br /&gt;
&amp;lt;math&amp;gt;R(0)=A(0) &amp;lt;/math&amp;gt;&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;,&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami (odwrotność PRF).&lt;br /&gt;
&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5504</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5504"/>
		<updated>2016-07-03T11:14:23Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2 f_{0} v \mbox{cos} \theta}{c}&amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&amp;lt;br&amp;gt;&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
Różniczkując powyższe dostajemy &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
oraz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
i stąd&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
oraz &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;R(0)=A(0) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami. Oznaczenie &amp;quot;PRF&amp;quot; pochodzi od skrótu [[wikipedia:Pulse_repetition_frequency|Pulse Repetition Frequency]] &amp;lt;br&amp;gt;&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
	<entry>
		<id>http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5503</id>
		<title>USG/Doppler</title>
		<link rel="alternate" type="text/html" href="http://brain.fuw.edu.pl/edu/index.php?title=USG/Doppler&amp;diff=5503"/>
		<updated>2016-07-03T11:12:39Z</updated>

		<summary type="html">&lt;p&gt;Mlew: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Metoda dopplerowska=&lt;br /&gt;
Do dyspozycji mamy zestaw zrekonstruowanych danych RF ([http://www.fuw.edu.pl/~jarekz/FUW-FID-2016/raw-data/usg3_doppler_circle_10lh.npy link]) z 64 kolejnych nadań pod stałym kątem (zerowym) falą płaską o parametrach:&lt;br /&gt;
&amp;lt;source lang = python&amp;gt;&lt;br /&gt;
f0 = 4e6 # Częstotliwość nadawcza [Hz]&lt;br /&gt;
z_step = 1.8970189701897084e-05 # Odległość między kolejnymi punktami w głębokości na siatce rekonstruowanego obrazu [m]&lt;br /&gt;
&lt;br /&gt;
PRF = 1000  # Pulse Repetition Frequency [Hz]&lt;br /&gt;
T_PRF = 1./PRF # czas między kolejnymi nadaniami [s]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Obrazowany jest przekrój fantomu przepływowego złożonego z rurek umieszczonych w materiale tkankopodobnym. &lt;br /&gt;
[[Plik:Rys_fantom_flow.png|200px|thumb|right|Zdjęcie fantomu przepływowego.]] &lt;br /&gt;
[[Plik:Rys_fantom_flow_przekroj.png|200px|thumb|right|Schemat obrazujący przekrój fantomu odpowiadający w przybliżeniu płaszczyźnie obrazowania.]] &lt;br /&gt;
Pompa wymusza jednostajny przepływ płynu krwiopodobnego znajdującego się w rurkach. Będziemy starali się wykorzystać metodę dopplerowską do stworzenia mapy obrazującej zwrot i prędkość przepływu. Średnie odchylenie dopplerowskie szacować będziemy przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Demodulacja sygnału RF==&lt;br /&gt;
Estymator autokorelacyjny stosowany jest na zdemodulowanym sygnale kwadraturowym I/Q (ang. In-Phase/Quadrature). Sygnał RF rejestrowany bezpośrednio z przetworników odbiorczych jest sygnałem rzeczywistym (zerowa część urojona) o pasmowej charakterystyce widmowej. Informacja istotna z naszego punktu widzenia położona jest w paśmie, którego środek znajduje się częstotliwości nadawczej; szerokość tego pasma zależna jest od fizycznych właściwości głowicy ultradźwiękowej i nazywana jest pasmem przenoszenia głowicy. Demodulacja jest operacją pozwalającą na przekształcenie takiego sygnału w sygnał zespolony o paśmie położonym wokół częstotliwości zerowej. Taki zabieg pozwala na zmniejszenie częstotliwości próbkowania - potencjalnie poniżej częstotliwości Nyquista określonej dla składowych sygnału niezdemodulowanego.&lt;br /&gt;
[[Plik:Rys_demodulation.png|200px|thumb|right|Widmo sygnału: a) przed demodulacją; b) po demodulacji; c) po demodulacji i filtrowaniu.]]&lt;br /&gt;
&lt;br /&gt;
Demodulację możemy przeprowadzić zarówno na danych surowych RF, jak i na danych po rekonstrukcji. W naszym wypadku zastosujemy to drugie rozwiązanie.&lt;br /&gt;
&lt;br /&gt;
Na początku stworzymy funkcję dokonującą demodulacji każdego z obrazów, tj. dla każdego próbki o współrzędnych &amp;lt;math&amp;gt;(x,y)&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;math&amp;gt;IQ(x,y)=RF(x,y)\cdot e^{-i\cdot2\pi f_{0}t} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;IQ&amp;lt;/math&amp;gt; - sygnał po demodulacji; &amp;lt;math&amp;gt;RF&amp;lt;/math&amp;gt; - sygnał przed demodulacją; &amp;lt;math&amp;gt;t&amp;lt;/math&amp;gt; - czas odpowiadający momentowi akwizycji próbki z danej głębokości; możemy przyjąć uproszczone założenie, że:&lt;br /&gt;
&amp;lt;math&amp;gt;t=2y/c &amp;lt;/math&amp;gt;; jak widać, pierwszy wymiar (szerokość) jest w naszej procedurze nieistotny.&lt;br /&gt;
Po demodulacji sygnał należy przefiltrować dolnoprzepustowo w zakresie pasma podstawowego (tzw. baseband). W naszym wypadku wystarczający powinien być filtr dolnoprzepustowy o częstotliwości odcięcia równej 5.55MHz.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Do wykonania:&amp;lt;/b&amp;gt;&lt;br /&gt;
# Zbadać widmo amplitudowe sygnału przed i po demodulacji (po filtrowaniu). Jak zmieniło się widmo? Gdzie jest położona średnia widma? Czy rozkłady dla ujemnych i dodatnich częstotliwości są swoimi odbiciami?&lt;br /&gt;
# Porównać widmo amplitudowe sygnału zdemodulowanego przed i po filtracji. Jakich składowych w częstości się pozbyliśmy (nie licząc szumu)?&lt;br /&gt;
# Zmienić w demodulacji wartość częstotliwości nośnej (np. zmniejszyć o połowę) i ponownie porównać widmo przed i po demodulacji.&lt;br /&gt;
&lt;br /&gt;
==Estymator autokorelacyjny==&lt;br /&gt;
===Rys teoretyczny===&lt;br /&gt;
Dotychczas traktowaliśmy rekonstruowane obrazy jako sygnały dwuwymiarowe. Teraz, do zmierzenia średniej prędkości obiektów poruszających się w danym punkcie, konieczna będzie analiza wielu następujących po sobie obrazów, które zostały zebrane ze stałym interwałem czasowym (tzw. PRF - Pulse Repetition Frequency). W poniższych rozważaniach pomijamy wymiary przestrzenne - całe rozumowania przeprowadzone są dla sygnału &amp;lt;math&amp;gt;s(i)&amp;lt;/math&amp;gt; na ustalonej głębokości i szerokości. Należy mieć na uwadze, że w praktyce ciężko mówić o estymacji prędkości w punkcie, ponieważ w naszej procedurze estymacji uwzględniamy efektywnie informacje z pewnego obszaru pomiarowego (energia danego piksela zawiera informację o obiektach z pewnego obszaru).&lt;br /&gt;
Średnią prędkość będziemy mogli obliczyć korzystając ze średniego przesunięcia dopplerowskiego &amp;lt;math&amp;gt;\Delta f&amp;lt;/math&amp;gt; w oparciu o szkolny wzór na [[Fizyka_III/Fale_dźwiękowe#Efekt_Dopplera|częstotliwość Dopplera]]:&lt;br /&gt;
&amp;lt;math&amp;gt;\Delta f=\frac{2f_{0}v\mbox{cos}\theta}{c}&amp;lt;/math&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;v&amp;lt;/math&amp;gt; średnia prędkość w punkcie pomiarowym; &amp;lt;math&amp;gt;\theta&amp;lt;/math&amp;gt; kąt między kierunkiem przepływu a wiązką nadawczą.&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Przesunięcie dopplerowskie jest różnicą między średnią częstotliwością &amp;lt;math&amp;gt;f_0&amp;lt;/math&amp;gt; sygnału nadanego a średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; sygnału odebranego (pochodzącego od rozpraszaczy przemieszczających się w kierunku do lub od głowicy). Przypomnijmy, że zdemodulowany sygnał jest sygnałem o widmie pasmowym położonym w pobliżu częstości zerowej. Pozwala nam to przyjąć, że średnie przesunięcie częstotliwości odpowiada średniej częstotliwości tego sygnału&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\Delta f = f_s-f_0 = f_s&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; Średnią częstotliwość możemy estymować na wiele sposób - np. licząc średnią ważoną z widma otrzymanego przez dyskretną transformację Fouriera. My zastosujemy do tego estymator autokorelacyjny&amp;lt;ref&amp;gt;Kasai, Chihiro, et al. &amp;quot;Real-time two-dimensional blood flow imaging using an autocorrelation technique.&amp;quot; IEEE Trans. Sonics Ultrason 32.3 (1985): 458-464.&amp;lt;/ref&amp;gt;, oparty na czasowej reprezentacji sygnału.&amp;lt;br&amp;gt;&lt;br /&gt;
Średnia częstość kołowa &amp;lt;math&amp;gt;\bar{\omega}&amp;lt;/math&amp;gt; widma dopplerowskiego &amp;lt;math&amp;gt;P(\omega)&amp;lt;/math&amp;gt; może być zdefiniowana jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=\frac{\int^{\infty}_{-\infty}\omega P(\omega)\mbox{d}\omega}{P(\omega)\mbox{d}\omega}&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Jednocześnie, przy założeniu słabej stacjonarności sygnału dopplerowskiego, na mocy [[Twierdzenie_Wienera-Chinczyna|twierdzenia Wienera-Chinczyna]], funkcję autokorelacji &amp;lt;math&amp;gt;R(\tau)&amp;lt;/math&amp;gt; tego sygnału możemy wyrazić jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;R(\tau)=\int^{\infty}_{-\infty} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
Różniczkując powyższe dostajemy &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\dot{R}(\tau)=j\int^{\infty}_{-\infty} \omega P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
oraz &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\ddot{R}(\tau)=-\int^{\infty}_{-\infty} \omega^{2} P(\omega)e^{j\omega\tau}\mbox{d}\omega&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Stąd, częstotliwość średnia możemy być również przedstawiona jako &amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;\bar{\omega}=-j\frac{\dot{R}(0)}{R(0)}&amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
W celu uproszczenia obliczeń przyjmuje się często następujące uproszczenie&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;R(\tau)= |R(\tau)|e^{j\phi(\tau)}=A(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;A(\tau)&amp;lt;/math&amp;gt; jest funkcją parzystą i &amp;lt;math&amp;gt;e^{j\phi(\tau)}&amp;lt;/math&amp;gt; jest funkcją nieparzystą. Wtedy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\dot{R}(\tau)=(\dot{A}(\tau)+jA(\tau)\dot{\phi}(\tau)e^{j\phi(\tau)} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
i stąd&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\dot{R}(0)=jA(0)\dot{\phi}(0) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
oraz &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;R(0)=A(0) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Korzystając ze wcześniejszych równań dostajemy&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\dot{\phi}(0)\approx \frac{\phi(T_{PRF})-\phi(0)}{T_{PRF}}=\frac{\phi(T_{PRF})}{T_{PRF}}=\frac{1}{T_{PRF}}\frac{\mbox{Im}(R(T_{PRF}))}{\mbox{Re}(R(T_{PRF}))} &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt; - czas między kolejnymi strzałami. Oznaczenie &amp;quot;PRF&amp;quot; pochodzi od skrótu [[wikipedia:Pulse_repetition_frequency|Pulse Repetition Frequency]] &amp;lt;br&amp;gt;&lt;br /&gt;
====Estymator Millera-Rochwargera====&lt;br /&gt;
Wartość &amp;lt;math&amp;gt;R(T_{PRF})&amp;lt;/math&amp;gt; estymować możemy np. w oparciu o estymator Millera-Rochwargera &amp;lt;ref&amp;gt;Miller, Kenneth, and M. Rochwarger. &amp;quot;A covariance approach to spectral moment estimation.&amp;quot; IEEE Transactions on Information Theory 18.5 (1972): 588-596.&amp;lt;/ref&amp;gt;. Jest to [[wikipedia:Maximum_likelihood_estimation|estymator maksymalnej wiarygodności]] (maximum likehood estimator). Estymator ten jest skonstruowany dla par obserwacji zespolonego procesu &amp;lt;math&amp;gt;s&amp;lt;/math&amp;gt; próbkowanych w równych odstępach czasu (w naszym przypadku &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). W naszym przypadku jako pary obserwacji traktuje się pary próbek z kolejnych par następujących po sobie pomiarów (oddzielonych wartością &amp;lt;math&amp;gt;T_{PRF}&amp;lt;/math&amp;gt;). Otrzymujemy wtedy oszacowanie wartości autokorelacji w oknie czasowym długości &amp;lt;math&amp;gt;N-1&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&amp;lt;math&amp;gt;\bar{\omega}=\frac{1}{T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Pamiętając zależność między średnią częstotliwością &amp;lt;math&amp;gt;f_s&amp;lt;/math&amp;gt; a średnią częstością kołową &amp;lt;math&amp;gt;fs=(1/2\pi)\bar{\omega}&amp;lt;/math&amp;gt; dostajemy &lt;br /&gt;
&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;f_s=\frac{1}{2\pi T_{PRF}}\mbox{arctan}\frac{Im(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}{Re(\sum^{N-2}_{i=0}s(i+1)\cdot \overline{s(i)})}  &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Proszę przygotować funkcję estymującą częstotliwość średnią w oparciu o powyższy estymator dla jednowymiarowego zespolonego sygnału.&lt;br /&gt;
&lt;br /&gt;
==Prezentacja Kolor==&lt;br /&gt;
Po estymacji średnich prędkości w obszarach odpowiadających punktom na siatce użytej do rekonstrukcji obrazu, możemy nałożyć taką mapę na obraz B-mode w celu uzyskania obrazu &amp;quot;Kolor&amp;quot;. Mając tablicę z danymi B-mode oraz tablicę prędkości, możemy otrzymać połączony obraz za pomocą poniższego skryptu:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt; &lt;br /&gt;
#BMode - tablica zrekonstruowanych danych po przefiltrowaniu, obwiedni itp.&lt;br /&gt;
#flow - tablica przepływów&lt;br /&gt;
Frame = Image.fromarray(np.uint8(cm.bone(BMode)*255)) &lt;br /&gt;
flowMask = np.copy(flow)&lt;br /&gt;
flowMask = np.abs(flowMask)&lt;br /&gt;
flowMask = flowMask/(np.max(flowMask))*255&lt;br /&gt;
&lt;br /&gt;
flow = flow+np.abs(np.min(flow))&lt;br /&gt;
flow = flow/np.max(flow)&lt;br /&gt;
&lt;br /&gt;
flow = Image.fromarray(np.uint8(cm.jet(flow)*255))&lt;br /&gt;
flowMask = Image.fromarray(np.uint8(flowMask), 'L')&lt;br /&gt;
flow.putalpha(flowMask)&lt;br /&gt;
        &lt;br /&gt;
Frame.paste(flow, (0,0), flow)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Zadanie===&lt;br /&gt;
Zaimplementować funkcję otrzymującą na wejściu trójwymiarową tablicę zawierającą obrazy RF z &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt; kolejnych chwil pomiarowych i zwracającą obrazy z nałożoną na nią mapą prędkości obliczonych przy użyciu estymatora autokorelacyjnego.&lt;br /&gt;
&lt;br /&gt;
==Filtracja obrazu==&lt;br /&gt;
Mapa częstości estymowana metodą autokorelacyjną jest dość wrażliwa na błędy estymacji powodowane m.in. obecność w sygnale informacji z dużego obszaru pomiarowego. Stosować można kilka metod mających na celu poprawę wynikowego obrazu - progowanie (zignorowanie względnie małych prędkości), rozpoznawanie ruchu i filtrowanie.&lt;br /&gt;
&lt;br /&gt;
===Rozpoznawanie ruchu===&lt;br /&gt;
Jedną z pierwszy obserwacji jakiej można dokonać, to zauważenie, że nasza mapa jest niezerowa w punktach w których nie spodziewamy się żadnego ruchu. Pewnym rozwiązaniem tego problemu może być zastosowanie prostego kryterium rozpoznawania ruchu. Możemy przyjąć, że sygnał pochodzący od struktur pozostających w spoczynku powinien być stały w czasie. W praktyce sygnały takie różnić będą się głównie o składową szumu elektronicznego. Jednocześnie, sygnał pochodzący od ruchomych struktur będzie charakteryzować się względnie dużą zmiennością w czasie. &amp;lt;br&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Zaimplementować procedurę zerującą estymatę prędkości w punkcie, jeśli średnia różnica między wartościami sygnału w tym punkcie w kolejnych chwilach czasu jest względnie mała (próg proszę dobrać eksperymentalnie - zaczynając np. od progu 10% średniej różnicy w obrazie).&lt;br /&gt;
&lt;br /&gt;
===Filtr medianowy===&lt;br /&gt;
Dobrym rozwiązaniem w tego typu przypadkach jest zastosowanie filtru medianowego. Filtr medianowy przekształca wartość w punkcie na medianę wartości sygnału w ustalonej liczbie sąsiednich próbek (w obu wymiarach):&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;math&amp;gt;s_{med}(x,y) = \sum^{K-1}_{i=0}\sum^{K-1}_{j=0}s(x+i,y+j) &amp;lt;/math&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
gdzie &amp;lt;math&amp;gt;K&amp;lt;/math&amp;gt; - rozmiar okna filtru.&lt;br /&gt;
Filtr taki usuwa skrajne wartości w dużo większym stopniu niż np. filtr oparty o średnią arytmetyczną. W bibliotece scipy istnieje gotowa funkcja filtrująca tablicę filtrem medianowym:&lt;br /&gt;
&amp;lt;source lang=python&amp;gt;&lt;br /&gt;
scipy.signal.medfilt2d(array, K)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
====Zadanie====&lt;br /&gt;
Porównać mapy prędkości przed i po filtracji medianowej (dla kilku różnych rozmiarów okna filtracji)&lt;/div&gt;</summary>
		<author><name>Mlew</name></author>
		
	</entry>
</feed>