comparison OrthancFramework/Sources/Images/ImageProcessing.cpp @ 4297:785a2713323e

abi continued
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 05 Nov 2020 17:20:49 +0100
parents 9279de56a405
children b30a8de92ad9
comparison
equal deleted inserted replaced
4296:3b70a2e6a06c 4297:785a2713323e
560 throw OrthancException(ErrorCode_IncompatibleImageSize); 560 throw OrthancException(ErrorCode_IncompatibleImageSize);
561 } 561 }
562 562
563 switch (source.GetFormat()) 563 switch (source.GetFormat())
564 { 564 {
565 case Orthanc::PixelFormat_Float32: 565 case PixelFormat_Float32:
566 { 566 {
567 switch (target.GetFormat()) 567 switch (target.GetFormat())
568 { 568 {
569 case Orthanc::PixelFormat_Grayscale8: 569 case PixelFormat_Grayscale8:
570 ApplyWindowingInternal<uint8_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 570 ApplyWindowingInternal<uint8_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
571 break; 571 break;
572 case Orthanc::PixelFormat_Grayscale16: 572 case PixelFormat_Grayscale16:
573 ApplyWindowingInternal<uint16_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 573 ApplyWindowingInternal<uint16_t, float>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
574 break; 574 break;
575 default: 575 default:
576 throw OrthancException(ErrorCode_NotImplemented); 576 throw OrthancException(ErrorCode_NotImplemented);
577 } 577 }
578 };break; 578 };break;
579 case Orthanc::PixelFormat_Grayscale8: 579 case PixelFormat_Grayscale8:
580 { 580 {
581 switch (target.GetFormat()) 581 switch (target.GetFormat())
582 { 582 {
583 case Orthanc::PixelFormat_Grayscale8: 583 case PixelFormat_Grayscale8:
584 ApplyWindowingInternal<uint8_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 584 ApplyWindowingInternal<uint8_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
585 break; 585 break;
586 case Orthanc::PixelFormat_Grayscale16: 586 case PixelFormat_Grayscale16:
587 ApplyWindowingInternal<uint16_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 587 ApplyWindowingInternal<uint16_t, uint8_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
588 break; 588 break;
589 default: 589 default:
590 throw OrthancException(ErrorCode_NotImplemented); 590 throw OrthancException(ErrorCode_NotImplemented);
591 } 591 }
592 };break; 592 };break;
593 case Orthanc::PixelFormat_Grayscale16: 593 case PixelFormat_Grayscale16:
594 { 594 {
595 switch (target.GetFormat()) 595 switch (target.GetFormat())
596 { 596 {
597 case Orthanc::PixelFormat_Grayscale8: 597 case PixelFormat_Grayscale8:
598 ApplyWindowingInternal<uint8_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 598 ApplyWindowingInternal<uint8_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
599 break; 599 break;
600 case Orthanc::PixelFormat_Grayscale16: 600 case PixelFormat_Grayscale16:
601 ApplyWindowingInternal<uint16_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert); 601 ApplyWindowingInternal<uint16_t, uint16_t>(target, source, windowCenter, windowWidth, rescaleSlope, rescaleIntercept, invert);
602 break; 602 break;
603 default: 603 default:
604 throw OrthancException(ErrorCode_NotImplemented); 604 throw OrthancException(ErrorCode_NotImplemented);
605 } 605 }
1553 1553
1554 1554
1555 1555
1556 namespace 1556 namespace
1557 { 1557 {
1558 template <Orthanc::PixelFormat Format> 1558 template <PixelFormat Format>
1559 class BresenhamPixelWriter 1559 class BresenhamPixelWriter
1560 { 1560 {
1561 private: 1561 private:
1562 typedef typename PixelTraits<Format>::PixelType PixelType; 1562 typedef typename PixelTraits<Format>::PixelType PixelType;
1563 1563
1564 Orthanc::ImageAccessor& image_; 1564 ImageAccessor& image_;
1565 PixelType value_; 1565 PixelType value_;
1566 1566
1567 void PlotLineLow(int x0, 1567 void PlotLineLow(int x0,
1568 int y0, 1568 int y0,
1569 int x1, 1569 int x1,
1627 d = d + 2 * dx; 1627 d = d + 2 * dx;
1628 } 1628 }
1629 } 1629 }
1630 1630
1631 public: 1631 public:
1632 BresenhamPixelWriter(Orthanc::ImageAccessor& image, 1632 BresenhamPixelWriter(ImageAccessor& image,
1633 int64_t value) : 1633 int64_t value) :
1634 image_(image), 1634 image_(image),
1635 value_(PixelTraits<Format>::IntegerToPixel(value)) 1635 value_(PixelTraits<Format>::IntegerToPixel(value))
1636 { 1636 {
1637 } 1637 }
1638 1638
1639 BresenhamPixelWriter(Orthanc::ImageAccessor& image, 1639 BresenhamPixelWriter(ImageAccessor& image,
1640 const PixelType& value) : 1640 const PixelType& value) :
1641 image_(image), 1641 image_(image),
1642 value_(value) 1642 value_(value)
1643 { 1643 {
1644 } 1644 }
1698 int y1, 1698 int y1,
1699 int64_t value) 1699 int64_t value)
1700 { 1700 {
1701 switch (image.GetFormat()) 1701 switch (image.GetFormat())
1702 { 1702 {
1703 case Orthanc::PixelFormat_Grayscale8: 1703 case PixelFormat_Grayscale8:
1704 { 1704 {
1705 BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale8> writer(image, value); 1705 BresenhamPixelWriter<PixelFormat_Grayscale8> writer(image, value);
1706 writer.DrawSegment(x0, y0, x1, y1); 1706 writer.DrawSegment(x0, y0, x1, y1);
1707 break; 1707 break;
1708 } 1708 }
1709 1709
1710 case Orthanc::PixelFormat_Grayscale16: 1710 case PixelFormat_Grayscale16:
1711 { 1711 {
1712 BresenhamPixelWriter<Orthanc::PixelFormat_Grayscale16> writer(image, value); 1712 BresenhamPixelWriter<PixelFormat_Grayscale16> writer(image, value);
1713 writer.DrawSegment(x0, y0, x1, y1); 1713 writer.DrawSegment(x0, y0, x1, y1);
1714 break; 1714 break;
1715 } 1715 }
1716 1716
1717 case Orthanc::PixelFormat_SignedGrayscale16: 1717 case PixelFormat_SignedGrayscale16:
1718 { 1718 {
1719 BresenhamPixelWriter<Orthanc::PixelFormat_SignedGrayscale16> writer(image, value); 1719 BresenhamPixelWriter<PixelFormat_SignedGrayscale16> writer(image, value);
1720 writer.DrawSegment(x0, y0, x1, y1); 1720 writer.DrawSegment(x0, y0, x1, y1);
1721 break; 1721 break;
1722 } 1722 }
1723 1723
1724 default: 1724 default:
1725 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1725 throw OrthancException(ErrorCode_NotImplemented);
1726 } 1726 }
1727 } 1727 }
1728 1728
1729 1729
1730 void ImageProcessing::DrawLineSegment(ImageAccessor& image, 1730 void ImageProcessing::DrawLineSegment(ImageAccessor& image,
1737 uint8_t blue, 1737 uint8_t blue,
1738 uint8_t alpha) 1738 uint8_t alpha)
1739 { 1739 {
1740 switch (image.GetFormat()) 1740 switch (image.GetFormat())
1741 { 1741 {
1742 case Orthanc::PixelFormat_BGRA32: 1742 case PixelFormat_BGRA32:
1743 { 1743 {
1744 PixelTraits<Orthanc::PixelFormat_BGRA32>::PixelType pixel; 1744 PixelTraits<PixelFormat_BGRA32>::PixelType pixel;
1745 pixel.red_ = red; 1745 pixel.red_ = red;
1746 pixel.green_ = green; 1746 pixel.green_ = green;
1747 pixel.blue_ = blue; 1747 pixel.blue_ = blue;
1748 pixel.alpha_ = alpha; 1748 pixel.alpha_ = alpha;
1749 1749
1750 BresenhamPixelWriter<Orthanc::PixelFormat_BGRA32> writer(image, pixel); 1750 BresenhamPixelWriter<PixelFormat_BGRA32> writer(image, pixel);
1751 writer.DrawSegment(x0, y0, x1, y1); 1751 writer.DrawSegment(x0, y0, x1, y1);
1752 break; 1752 break;
1753 } 1753 }
1754 1754
1755 case Orthanc::PixelFormat_RGBA32: 1755 case PixelFormat_RGBA32:
1756 { 1756 {
1757 PixelTraits<Orthanc::PixelFormat_RGBA32>::PixelType pixel; 1757 PixelTraits<PixelFormat_RGBA32>::PixelType pixel;
1758 pixel.red_ = red; 1758 pixel.red_ = red;
1759 pixel.green_ = green; 1759 pixel.green_ = green;
1760 pixel.blue_ = blue; 1760 pixel.blue_ = blue;
1761 pixel.alpha_ = alpha; 1761 pixel.alpha_ = alpha;
1762 1762
1763 BresenhamPixelWriter<Orthanc::PixelFormat_RGBA32> writer(image, pixel); 1763 BresenhamPixelWriter<PixelFormat_RGBA32> writer(image, pixel);
1764 writer.DrawSegment(x0, y0, x1, y1); 1764 writer.DrawSegment(x0, y0, x1, y1);
1765 break; 1765 break;
1766 } 1766 }
1767 1767
1768 case Orthanc::PixelFormat_RGB24: 1768 case PixelFormat_RGB24:
1769 { 1769 {
1770 PixelTraits<Orthanc::PixelFormat_RGB24>::PixelType pixel; 1770 PixelTraits<PixelFormat_RGB24>::PixelType pixel;
1771 pixel.red_ = red; 1771 pixel.red_ = red;
1772 pixel.green_ = green; 1772 pixel.green_ = green;
1773 pixel.blue_ = blue; 1773 pixel.blue_ = blue;
1774 1774
1775 BresenhamPixelWriter<Orthanc::PixelFormat_RGB24> writer(image, pixel); 1775 BresenhamPixelWriter<PixelFormat_RGB24> writer(image, pixel);
1776 writer.DrawSegment(x0, y0, x1, y1); 1776 writer.DrawSegment(x0, y0, x1, y1);
1777 break; 1777 break;
1778 } 1778 }
1779 1779
1780 default: 1780 default:
1781 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1781 throw OrthancException(ErrorCode_NotImplemented);
1782 } 1782 }
1783 } 1783 }
1784 1784
1785 void ComputePolygonExtent(int32_t& left, int32_t& right, int32_t& top, int32_t& bottom, const std::vector<ImageProcessing::ImagePoint>& points) 1785 void ComputePolygonExtent(int32_t& left, int32_t& right, int32_t& top, int32_t& bottom, const std::vector<ImageProcessing::ImagePoint>& points)
1786 { 1786 {
1843 for (size_t i = 0; i < points.size(); i++) 1843 for (size_t i = 0; i < points.size(); i++)
1844 { 1844 {
1845 if (points[i].GetX() < 0 || points[i].GetX() >= imageWidth 1845 if (points[i].GetX() < 0 || points[i].GetX() >= imageWidth
1846 || points[i].GetY() < 0 || points[i].GetY() >= imageHeight) 1846 || points[i].GetY() < 0 || points[i].GetY() >= imageHeight)
1847 { 1847 {
1848 throw Orthanc::OrthancException(ErrorCode_ParameterOutOfRange); 1848 throw OrthancException(ErrorCode_ParameterOutOfRange);
1849 } 1849 }
1850 cpx.push_back((double)points[i].GetX()); 1850 cpx.push_back((double)points[i].GetX());
1851 cpy.push_back((double)points[i].GetY()); 1851 cpy.push_back((double)points[i].GetY());
1852 } 1852 }
1853 1853
1931 const std::vector<ImagePoint>& points, 1931 const std::vector<ImagePoint>& points,
1932 int64_t value) 1932 int64_t value)
1933 { 1933 {
1934 switch (image.GetFormat()) 1934 switch (image.GetFormat())
1935 { 1935 {
1936 case Orthanc::PixelFormat_Grayscale8: 1936 case PixelFormat_Grayscale8:
1937 { 1937 {
1938 FillPolygon_<Orthanc::PixelFormat_Grayscale8>(image, points, value); 1938 FillPolygon_<PixelFormat_Grayscale8>(image, points, value);
1939 break; 1939 break;
1940 } 1940 }
1941 case Orthanc::PixelFormat_Grayscale16: 1941 case PixelFormat_Grayscale16:
1942 { 1942 {
1943 FillPolygon_<Orthanc::PixelFormat_Grayscale16>(image, points, value); 1943 FillPolygon_<PixelFormat_Grayscale16>(image, points, value);
1944 break; 1944 break;
1945 } 1945 }
1946 case Orthanc::PixelFormat_SignedGrayscale16: 1946 case PixelFormat_SignedGrayscale16:
1947 { 1947 {
1948 FillPolygon_<Orthanc::PixelFormat_SignedGrayscale16>(image, points, value); 1948 FillPolygon_<PixelFormat_SignedGrayscale16>(image, points, value);
1949 break; 1949 break;
1950 } 1950 }
1951 default: 1951 default:
1952 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented); 1952 throw OrthancException(ErrorCode_NotImplemented);
1953 } 1953 }
1954 } 1954 }
1955 1955
1956 1956
1957 template <PixelFormat Format> 1957 template <PixelFormat Format>
2170 2170
2171 2171
2172 // This is a slow implementation of horizontal convolution on one 2172 // This is a slow implementation of horizontal convolution on one
2173 // individual channel, that checks for out-of-image values 2173 // individual channel, that checks for out-of-image values
2174 template <typename RawPixel, unsigned int ChannelsCount> 2174 template <typename RawPixel, unsigned int ChannelsCount>
2175 static float GetHorizontalConvolutionFloatSecure(const Orthanc::ImageAccessor& source, 2175 static float GetHorizontalConvolutionFloatSecure(const ImageAccessor& source,
2176 const std::vector<float>& horizontal, 2176 const std::vector<float>& horizontal,
2177 size_t horizontalAnchor, 2177 size_t horizontalAnchor,
2178 unsigned int x, 2178 unsigned int x,
2179 unsigned int y, 2179 unsigned int y,
2180 float leftBorder, 2180 float leftBorder,