pax_global_header00006660000000000000000000000064146723241770014527gustar00rootroot0000000000000052 comment=fb9e772ecbceaf7e258fa38e2c2ad6c1fb62e719 jeolib-miallib-1.1.6/000077500000000000000000000000001467232417700144075ustar00rootroot00000000000000jeolib-miallib-1.1.6/.gitignore000066400000000000000000000002661467232417700164030ustar00rootroot00000000000000core/build/ xlisp/build/ #swig/ core/c/banner.h xlisp/c/banner_mialib.h core/c/alloc.c core/c/alloc.h core/c/cluster.c core/c/cluster.h core/c/error.c core/c/error.h core/c/graph.c jeolib-miallib-1.1.6/CMakeLists.txt000066400000000000000000000327541467232417700171620ustar00rootroot00000000000000############################################################################### # Author(s): Pieter.Kempeneers@ec.europa.eu # Copyright (C) 2000-2023 European Union (Joint Research Centre) # This file is part of miallib. # miallib is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # miallib is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with miallib. If not, see . ############################################################################### ## need to install # libopenblas-dev # libfftw3-mpi-dev cmake_minimum_required(VERSION 3.15) # The project's name and version project(miallib) # set(MIALLIB_LIB_NAME miallib_generic) set(MIALLIB_LIB_NAME miallib) set (MIALLIB_VERSION_MAJOR 1) set (MIALLIB_VERSION_MINOR 1) set (MIALLIB_VERSION_PATCH 6) set (MIALLIB_VERSION "${MIALLIB_VERSION_MAJOR}.${MIALLIB_VERSION_MINOR}.${MIALLIB_VERSION_PATCH}") set (MIALLIB_SOVERSION "${MIALLIB_VERSION_MAJOR}") set(PROCESS_IN_PARALLEL TRUE CACHE BOOL "Choose if miallib should be run in parallel") # build a CPack driven installer package INCLUDE (InstallRequiredSystemLibraries) SET(CPACK_COMPONENTS_ALL libraries headers) SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/COPYING") SET(CPACK_PACKAGE_VERSION_MAJOR "${MIALLIB_VERSION_MAJOR}") SET(CPACK_PACKAGE_VERSION_MINOR "${MIALLIB_VERSION_MINOR}") SET(CPACK_PACKAGE_VERSION_PATCH "${MIALLIB_VERSION_PATCH}") SET(CPACK_GENERATOR "DEB") SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Pieter Kempeneers") SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) # Set files to ignore list(APPEND CPACK_SOURCE_IGNORE_FILES "_CPack_Packages") list(APPEND CPACK_SOURCE_IGNORE_FILES ".gz") list(APPEND CPACK_SOURCE_IGNORE_FILES ".bz2") list(APPEND CPACK_SOURCE_IGNORE_FILES ".zip") list(APPEND CPACK_SOURCE_IGNORE_FILES ".svn") list(APPEND CPACK_SOURCE_IGNORE_FILES ".git") list(APPEND CPACK_SOURCE_IGNORE_FILES "HOWTORELEASE.txt") list(APPEND CPACK_SOURCE_IGNORE_FILES "CMakeCache.txt") list(APPEND CPACK_SOURCE_IGNORE_FILES "CPackConfig.cmake") list(APPEND CPACK_SOURCE_IGNORE_FILES "schemas") list(APPEND CPACK_SOURCE_IGNORE_FILES "/build/;~$;${CPACK_SOURCE_IGNORE_FILES}") SET(CPACK_DEB_COMPONENT_INSTALL YES) INCLUDE(CPack) CPACK_ADD_COMPONENT(libraries) CPACK_ADD_COMPONENT(headers) SET(CPACK_DEB_COMPONENT_INSTALL YES) SET(CPACK_COMPONENTS_ALL libraries headers) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake/modules") message(STATUS "cmake module path: ${CMAKE_MODULE_PATH}") set(MIALLIB_SRC_DIR ${PROJECT_SOURCE_DIR}/core/c) #simple way to get all src files, but not recommended # file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/core/*.c") # set(SOURCES # ${SRC_FILES} # ) set(MIALLIB_H ${MIALLIB_SRC_DIR}/miallib_convolve.h ${MIALLIB_SRC_DIR}/miallib_dem.h ${MIALLIB_SRC_DIR}/miallib_dist.h ${MIALLIB_SRC_DIR}/miallib_erodil.h ${MIALLIB_SRC_DIR}/miallib_format.h ${MIALLIB_SRC_DIR}/miallib_geodesy.h ${MIALLIB_SRC_DIR}/miallib_geometry.h ${MIALLIB_SRC_DIR}/miallib_hmt.h ${MIALLIB_SRC_DIR}/miallib_imem.h ${MIALLIB_SRC_DIR}/miallib_io.h ${MIALLIB_SRC_DIR}/miallib_label.h ${MIALLIB_SRC_DIR}/miallib_miscel.h ${MIALLIB_SRC_DIR}/miallib_opclo.h ${MIALLIB_SRC_DIR}/miallib_pointop.h ${MIALLIB_SRC_DIR}/miallib_proj.h ${MIALLIB_SRC_DIR}/miallib_segment.h ${MIALLIB_SRC_DIR}/miallib_stats.h ${MIALLIB_SRC_DIR}/miallib_swig.h ${MIALLIB_SRC_DIR}/mialtypes.h ${MIALLIB_SRC_DIR}/myhull.h ${MIALLIB_SRC_DIR}/op.h ) set(SOURCES ${MIALLIB_H} ${MIALLIB_SRC_DIR}/aflood.c ${MIALLIB_SRC_DIR}/alphacc.c ${MIALLIB_SRC_DIR}/alphatree.c ${MIALLIB_SRC_DIR}/alphatreetoCCs.c ${MIALLIB_SRC_DIR}/base.h ${MIALLIB_SRC_DIR}/b_def.h ${MIALLIB_SRC_DIR}/borderdetection.c ${MIALLIB_SRC_DIR}/borderdetection.h ${MIALLIB_SRC_DIR}/bresenham.c ${MIALLIB_SRC_DIR}/b_undef.h ${MIALLIB_SRC_DIR}/bytesex.h ${MIALLIB_SRC_DIR}/ced.c ${MIALLIB_SRC_DIR}/classification.c ${MIALLIB_SRC_DIR}/colconv.c ${MIALLIB_SRC_DIR}/complete.c ${MIALLIB_SRC_DIR}/compose.c ${MIALLIB_SRC_DIR}/convolve.c ${MIALLIB_SRC_DIR}/dbscan.c ${MIALLIB_SRC_DIR}/dcluster.c ${MIALLIB_SRC_DIR}/d_def.h ${MIALLIB_SRC_DIR}/dendro.c ${MIALLIB_SRC_DIR}/determineSize.c ${MIALLIB_SRC_DIR}/determineSize.h ${MIALLIB_SRC_DIR}/dirmean.c ${MIALLIB_SRC_DIR}/dist.c ${MIALLIB_SRC_DIR}/douglas-peucker.c ${MIALLIB_SRC_DIR}/douglas-peucker.h ${MIALLIB_SRC_DIR}/d_undef.h ${MIALLIB_SRC_DIR}/edgeweight.c ${MIALLIB_SRC_DIR}/efedt.c ${MIALLIB_SRC_DIR}/epc.c ${MIALLIB_SRC_DIR}/erodil.c ${MIALLIB_SRC_DIR}/fah.c ${MIALLIB_SRC_DIR}/fah.h ${MIALLIB_SRC_DIR}/f_def.h ${MIALLIB_SRC_DIR}/fifo.c ${MIALLIB_SRC_DIR}/fifo.h ${MIALLIB_SRC_DIR}/fillocarve.c ${MIALLIB_SRC_DIR}/flatdir.c ${MIALLIB_SRC_DIR}/flow.c ${MIALLIB_SRC_DIR}/format.c ${MIALLIB_SRC_DIR}/f_undef.h ${MIALLIB_SRC_DIR}/g32_def.h ${MIALLIB_SRC_DIR}/g32_undef.h ${MIALLIB_SRC_DIR}/g_def.h ${MIALLIB_SRC_DIR}/geodist.c ${MIALLIB_SRC_DIR}/geom.c ${MIALLIB_SRC_DIR}/ggeo.c ${MIALLIB_SRC_DIR}/grid.c ${MIALLIB_SRC_DIR}/gsl.c ${MIALLIB_SRC_DIR}/g_undef.h ${MIALLIB_SRC_DIR}/herkbl.c ${MIALLIB_SRC_DIR}/herk.c ${MIALLIB_SRC_DIR}/histo.c ${MIALLIB_SRC_DIR}/htop.c ${MIALLIB_SRC_DIR}/hull.c ${MIALLIB_SRC_DIR}/hullti.c ${MIALLIB_SRC_DIR}/i32_def.h ${MIALLIB_SRC_DIR}/i32_undef.h ${MIALLIB_SRC_DIR}/i64_def.h ${MIALLIB_SRC_DIR}/i64_undef.h ${MIALLIB_SRC_DIR}/imem.c ${MIALLIB_SRC_DIR}/imio2.c ${MIALLIB_SRC_DIR}/imio.c ${MIALLIB_SRC_DIR}/imio_gdal.c ${MIALLIB_SRC_DIR}/imio.h ${MIALLIB_SRC_DIR}/imstat.c ${MIALLIB_SRC_DIR}/indexx.c ${MIALLIB_SRC_DIR}/label.c ${MIALLIB_SRC_DIR}/labelccdissim.c ${MIALLIB_SRC_DIR}/labelccfastrim.c ${MIALLIB_SRC_DIR}/labelccmi.c ${MIALLIB_SRC_DIR}/labelccms.c ${MIALLIB_SRC_DIR}/labelccmsdissim.c ${MIALLIB_SRC_DIR}/labelccvar.c ${MIALLIB_SRC_DIR}/labelci.c ${MIALLIB_SRC_DIR}/labelcims.c ${MIALLIB_SRC_DIR}/labelvertex.c ${MIALLIB_SRC_DIR}/lerodil.c ${MIALLIB_SRC_DIR}/linepool.c ${MIALLIB_SRC_DIR}/ll_def.h ${MIALLIB_SRC_DIR}/ll_undef.h ${MIALLIB_SRC_DIR}/mblincomb.c ${MIALLIB_SRC_DIR}/mcisrg.c ${MIALLIB_SRC_DIR}/mcisrg.h ${MIALLIB_SRC_DIR}/miallib.h ${MIALLIB_SRC_DIR}/miscel.c ${MIALLIB_SRC_DIR}/mmlabel.c ${MIALLIB_SRC_DIR}/mslabel.c ${MIALLIB_SRC_DIR}/mslabel.h ${MIALLIB_SRC_DIR}/msmm.c ${MIALLIB_SRC_DIR}/mspa.c ${MIALLIB_SRC_DIR}/myhull.cc ${MIALLIB_SRC_DIR}/myhull.h ${MIALLIB_SRC_DIR}/natngbint.c ${MIALLIB_SRC_DIR}/newlabelcc.c ${MIALLIB_SRC_DIR}/oiht.c ${MIALLIB_SRC_DIR}/oiiz.c ${MIALLIB_SRC_DIR}/oiws.c ${MIALLIB_SRC_DIR}/outeredge.c ${MIALLIB_SRC_DIR}/ovlmatrix.c ${MIALLIB_SRC_DIR}/partition.c ${MIALLIB_SRC_DIR}/partorp.c ${MIALLIB_SRC_DIR}/phase_correlation.c ${MIALLIB_SRC_DIR}/pointop.c ${MIALLIB_SRC_DIR}/pqueue.c ${MIALLIB_SRC_DIR}/pqueueExact.c ${MIALLIB_SRC_DIR}/pqueueExact.h ${MIALLIB_SRC_DIR}/pqueue.h ${MIALLIB_SRC_DIR}/projection.c ${MIALLIB_SRC_DIR}/propagate.c ${MIALLIB_SRC_DIR}/rank.c ${MIALLIB_SRC_DIR}/recons.c ${MIALLIB_SRC_DIR}/regionMean.c ${MIALLIB_SRC_DIR}/regionMean.h ${MIALLIB_SRC_DIR}/registration.c ${MIALLIB_SRC_DIR}/remsens.c ${MIALLIB_SRC_DIR}/rminmax.c ${MIALLIB_SRC_DIR}/s_def.h ${MIALLIB_SRC_DIR}/segmentation.c ${MIALLIB_SRC_DIR}/segmentation.h ${MIALLIB_SRC_DIR}/setreg.c ${MIALLIB_SRC_DIR}/setreglut.c ${MIALLIB_SRC_DIR}/setshft.c ${MIALLIB_SRC_DIR}/shade.c ${MIALLIB_SRC_DIR}/shm.c ${MIALLIB_SRC_DIR}/simplifyLine.c ${MIALLIB_SRC_DIR}/simplifyLine.h ${MIALLIB_SRC_DIR}/skel.c ${MIALLIB_SRC_DIR}/skelodthin.c ${MIALLIB_SRC_DIR}/srg.c ${MIALLIB_SRC_DIR}/s_undef.h ${MIALLIB_SRC_DIR}/switch.c ${MIALLIB_SRC_DIR}/transition.c ${MIALLIB_SRC_DIR}/u32_def.h ${MIALLIB_SRC_DIR}/u32_undef.h ${MIALLIB_SRC_DIR}/u64_def.h ${MIALLIB_SRC_DIR}/u64_undef.h ${MIALLIB_SRC_DIR}/uc_def.h ${MIALLIB_SRC_DIR}/uc_undef.h ${MIALLIB_SRC_DIR}/us_def.h ${MIALLIB_SRC_DIR}/us_undef.h ${MIALLIB_SRC_DIR}/uswilk.c ${MIALLIB_SRC_DIR}/vectorize.c ${MIALLIB_SRC_DIR}/vectorize.h ${MIALLIB_SRC_DIR}/writeShapeFile.c ${MIALLIB_SRC_DIR}/writeShapeFile.h ${MIALLIB_SRC_DIR}/writeSVG.c ${MIALLIB_SRC_DIR}/writeSVG.h ${MIALLIB_SRC_DIR}/wsfah.c ${MIALLIB_SRC_DIR}/wshed.c ) # core/c/banner.h message(STATUS "SOURCES: ${SOURCES}") # Setup output directories. set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib) option (BUILD_SHARED_LIBS "Build with shared library" ON) ############################################################################### # Define the miallib library. # add_library( ${MIALLIB_LIB_NAME} ${SRC_FILES}) add_library(${MIALLIB_LIB_NAME} ${SOURCES}) ############################################################################### SET_TARGET_PROPERTIES(${MIALLIB_LIB_NAME} PROPERTIES SOVERSION ${MIALLIB_SOVERSION} VERSION ${MIALLIB_VERSION} NAMESPACE ${MIALLIB_LIB_NAME}:: ) include_directories("core/c") find_package(PkgConfig REQUIRED) # Setup configure file # configure a header file to pass some of the CMake settings to the source code configure_file ( "cmake-config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/core/c/config_miallib.h") # configure_file ( "cmake-config.in" "${CMAKE_CURRENT_BINARY_DIR}/miallib-config" @ONLY ) include_directories("${CMAKE_CURRENT_BINARY_DIR}/core/c")# needed for config_miallib.h add_definitions(-DHAVE_CONFIG_H) include(GNUInstallDirs) set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/miallib CACHE PATH "Location of header files" ) set(LIBRARY_INSTALL_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Location of library files" ) #Generating Package Files include(CMakePackageConfigHelpers) configure_package_config_file( miallib-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/miallib-config.cmake INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/miallib PATH_VARS INCLUDE_INSTALL_DIR LIBRARY_INSTALL_DIR ) # Generate MIALLIBConfigVersion.cmake write_basic_package_version_file( ${CMAKE_CURRENT_BINARY_DIR}/miallib-config-version.cmake VERSION ${MIALLIB_VERSION} COMPATIBILITY AnyNewerVersion ) configure_file ( "cmake.pc.in" "miallib.pc" @ONLY) find_package(ZLIB REQUIRED) target_link_libraries(${MIALLIB_LIB_NAME} ${ZLIB_LIBRARIES}) include_directories(${ZLIB_INCLUDE_DIRS}) message(STATUS "Found ZLIB_INCLUDE_DIRS: ${ZLIB_INCLUDE_DIRS}") find_package(GDAL 3.00 REQUIRED) target_link_libraries(${MIALLIB_LIB_NAME} ${GDAL_LIBRARIES}) include_directories(${GDAL_INCLUDE_DIRS}) find_package(GeoTIFF) message(STATUS "Found GEOTIFF_INCLUDE_DIRS: ${GEOTIFF_INCLUDE_DIRS}") include_directories(${GEOTIFF_INCLUDE_DIR}) target_link_libraries(${MIALLIB_LIB_NAME} ${GEOTIFF_LIBRARIES}) find_package(TIFF) target_link_libraries(${MIALLIB_LIB_NAME} tiff) find_package(PROJ REQUIRED IMPORTED) message(STATUS "Found PROJ INCLUDE DIRS: ${PROJ_INCLUDE_DIRS}") target_link_libraries(${MIALLIB_LIB_NAME} ${PROJ_LIBRARIES}) message(STATUS "Found DL_LIBS: ${CMAKE_DL_LIBS}") target_link_libraries(${MIALLIB_LIB_NAME} ${CMAKE_DL_LIBS}) ### BEGIN FFTW pkg_search_module(FFTW REQUIRED fftw3 IMPORTED_TARGET) include_directories(PkgConfig::FFTW) link_libraries(PkgConfig::FFTW) #find_package(FFTW REQUIRED) message(STATUS "Found FFTW_LIBRARIES: ${FFTW_LIBRARIES}") message(STATUS "Found FFTW_INCLUDE_DIRS: ${FFTW_INCLUDE_DIRS}") target_link_libraries(${MIALLIB_LIB_NAME} ${FFTW_LIBRARIES}) if(PROCESS_IN_PARALLEL) find_package(OpenMP REQUIRED) set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set (CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") set(PARALLEL_BOOL 1) message(STATUS "parallel processing: ${PARALLEL_BOOL}") SET(CMAKE_C_FLAGS "-DOPENMP=${PARALLEL_BOOL}") target_link_libraries(${MIALLIB_LIB_NAME} OpenMP::OpenMP_CXX) # string(REPLACE ".so" "_omp.so" FFTW_OMP_LIBRARIES "${FFTW_LIBRARIES}") message(STATUS "FFTW_OMP_LIBRARIES: ${FFTW_OMP_LIBRARIES}") target_link_libraries(${MIALLIB_LIB_NAME} ${FFTW_OMP_LIBRARIES}) else(PROCESS_IN_PARALLEL) set(PARALLEL_BOOL 0) message(STATUS "parallel processing: ${PARALLEL_BOOL}") endif(PROCESS_IN_PARALLEL) find_package(PkgConfig REQUIRED) set(BLA_VENDOR OpenBLAS) set(CMAKE_C_FLAGS -fopenmp) #find_package(BLAS REQUIRED) find_package(GSL REQUIRED) if(GSL_FOUND) message(STATUS "Found GSL: ${GSL_LIBRARIES}") include_directories(${GSL_INCLUDE_DIRS}) add_definitions(-DGSL_DLL) target_link_libraries(${MIALLIB_LIB_NAME} ${GSL_LIBRARIES}) endif() find_package(SHAPELIB REQUIRED) message(STATUS "Found SHAPELIB libraries: ${SHAPELIB_LIBRARIES}") message(STATUS "Found SHAPELIB include dir: ${SHAPELIB_INCLUDE_DIRS}") include_directories(${SHAPELIB_INCLUDE_DIRS}) target_link_libraries(${MIALLIB_LIB_NAME} ${SHAPELIB_LIBRARIES}) add_definitions(-DSHAPE_DLL) INSTALL(TARGETS ${MIALLIB_LIB_NAME} EXPORT "${MIALLIB_LIB_NAME}" COMPONENT libraries LIBRARY DESTINATION lib) INSTALL(FILES ${MIALLIB_H} DESTINATION include/miallib/) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/miallib-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/miallib-config-version.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/miallib COMPONENT headers ) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/miallib.pc DESTINATION lib/pkgconfig ) jeolib-miallib-1.1.6/COPYING000066400000000000000000001045151467232417700154500ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . jeolib-miallib-1.1.6/README.md000066400000000000000000000011731467232417700156700ustar00rootroot00000000000000Welcome to miallib! # Installation for pyjeo This part explains how to install miallib as a dependency for pyjeo ## Build dependencies ``` sudo apt update DEBIAN_FRONTEND='noninteractive' sudo apt install -yq \ git \ build-essential \ cmake \ libgsl-dev \ libgsl0-dev \ libfann-dev \ libgeotiff-dev \ libfftw3-dev \ libproj-dev \ libjsoncpp-dev \ libgdal-dev \ libssl-dev \ swig \ uthash-dev \ libopenblas-dev \ libshp-dev ``` To build and install the miallib library via cmake for pyjeo: ``` mkdir build cd build cmake .. cmake --build . sudo cmake --install . ```jeolib-miallib-1.1.6/cmake-config.h.in000066400000000000000000000004721467232417700175130ustar00rootroot00000000000000// the configured options and settings for miallib #define MIALLIB_VERSION_MAJOR @MIALLIB_VERSION_MAJOR@ #define MIALLIB_VERSION_MINOR @MIALLIB_VERSION_MINOR@ #define MIALLIB_VERSION_PATCH @MIALLIB_VERSION_PATCH@ #define MIALLIB_VERSION @MIALLIB_VERSION_MAJOR@ #ifndef OPENMP #define OPENMP @PARALLEL_BOOL@ #endif jeolib-miallib-1.1.6/cmake-config.in000066400000000000000000000014271467232417700172660ustar00rootroot00000000000000#!/bin/sh usage() { cat <&2 fi while test $# -gt 0; do case "$1" in -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; *) optarg= ;; esac case $1 in --prefix) echo @CMAKE_INSTALL_PREFIX@ ;; --version) echo @MIALLIB_PACKAGE_VERSION@ ;; --cflags) echo -I@CMAKE_INSTALL_PREFIX@/include ;; --libs) echo -L@CMAKE_INSTALL_PREFIX@/@PROJECT_LIBRARY_DIR@ ;; --ldflags) echo @CMAKE_INSTALL_PREFIX@/@PROJECT_LIBRARY_DIR@ ;; --includes) echo @CMAKE_INSTALL_PREFIX@/include ;; esac shift done jeolib-miallib-1.1.6/cmake.pc.in000066400000000000000000000004471467232417700164250ustar00rootroot00000000000000prefix=@CMAKE_INSTALL_PREFIX@ exec_prefix=@CMAKE_INSTALL_PREFIX@/bin libdir=@CMAKE_INSTALL_PREFIX@/lib includedir=@CMAKE_INSTALL_PREFIX@/include Name: miallib Description: API library for miallib Requires: Version: @PACKAGE_VERSION@ Libs: -L${libdir} -lmiallib Cflags: -I${includedir}/miallib jeolib-miallib-1.1.6/cmake/000077500000000000000000000000001467232417700154675ustar00rootroot00000000000000jeolib-miallib-1.1.6/cmake/modules/000077500000000000000000000000001467232417700171375ustar00rootroot00000000000000jeolib-miallib-1.1.6/cmake/modules/FindGeoTIFF.cmake000066400000000000000000000054111467232417700221260ustar00rootroot00000000000000# #* Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) #* #* This file is part of Orfeo Toolbox #* #* https://www.orfeo-toolbox.org/ #* #* Licensed under the Apache License, Version 2.0 (the "License"); #* you may not use this file except in compliance with the License. #* You may obtain a copy of the License at #* #* http://www.apache.org/licenses/LICENSE-2.0 #* #* Unless required by applicable law or agreed to in writing, software #* distributed under the License is distributed on an "AS IS" BASIS, #* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #* See the License for the specific language governing permissions and #* limitations under the License. # - Find GEOTIFF library # Find the native GEOTIFF includes and library # # GEOTIFF_FOUND - True if GEOTIFF found. # GEOTIFF_INCLUDE_DIRS - where to find geotiff.h # GEOTIFF_LIBRARIES - List of libraries to link when using GEOTIFF. # GEOTIFF_VERSION - version string # GEOTIFF_VERSION_MAJOR - version major number # GEOTIFF_VERSION_MINOR - version minor number # GEOTIFF_VERSION_PATCH - version patch number # GEOTIFF_VERSION_NUMBER - version number ((major*100)+minor)*100+patch # find_path( GEOTIFF_INCLUDE_DIR geotiff.h PATH_SUFFIXES geotiff libgeotiff ) if(EXISTS "${GEOTIFF_INCLUDE_DIR}/geotiff.h") file(READ "${GEOTIFF_INCLUDE_DIR}/geotiff.h" _geotiff_h_CONTENTS) string(REGEX REPLACE ".*# *define +LIBGEOTIFF_VERSION +([0-9])([0-9])([0-9])([0-9]).*" "\\1" GEOTIFF_VERSION_MAJOR "${_geotiff_h_CONTENTS}") string(REGEX REPLACE ".*# *define +LIBGEOTIFF_VERSION +([0-9])([0-9])([0-9])([0-9]).*" "\\2" GEOTIFF_VERSION_MINOR "${_geotiff_h_CONTENTS}") string(REGEX REPLACE ".*# *define +LIBGEOTIFF_VERSION +([0-9])([0-9])([0-9])([0-9]).*" "\\3" GEOTIFF_VERSION_PATCH "${_geotiff_h_CONTENTS}") set(GEOTIFF_VERSION "${GEOTIFF_VERSION_MAJOR}.${GEOTIFF_VERSION_MINOR}.${GEOTIFF_VERSION_PATCH}") math(EXPR GEOTIFF_VERSION_NUMBER "((${GEOTIFF_VERSION_MAJOR})*100+${GEOTIFF_VERSION_MINOR})*100+${GEOTIFF_VERSION_PATCH}") else() if(NOT GEOTIFF_FIND_QUIETLY) message(WARNING "geotiff.h not found !") endif() endif() set( GEOTIFF_NAMES ${GEOTIFF_NAMES} geotiff_i geotiff libgeotiff_i libgeotiff ) find_library( GEOTIFF_LIBRARY NAMES ${GEOTIFF_NAMES} ) mark_as_advanced( GEOTIFF_INCLUDE_DIR GEOTIFF_LIBRARY ) # handle the QUIETLY and REQUIRED arguments and set GEOTIFF_FOUND to TRUE if # all listed variables are TRUE include(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS( GeoTIFF DEFAULT_MSG GEOTIFF_LIBRARY GEOTIFF_INCLUDE_DIR) if(GEOTIFF_FOUND) set( GEOTIFF_INCLUDE_DIRS ${GEOTIFF_INCLUDE_DIR} ) set( GEOTIFF_LIBRARIES ${GEOTIFF_LIBRARY} ) endif() jeolib-miallib-1.1.6/cmake/modules/FindPROJ.cmake000066400000000000000000000063671467232417700215300ustar00rootroot00000000000000# Distributed under the OSI-approved BSD 3-Clause License. See accompanying # file COPYING-CMAKE-SCRIPTS or https://cmake.org/licensing for details. #[=======================================================================[.rst: FindPROJ --------- CMake module to search for PROJ(PROJ.4 and PROJ) library On success, the macro sets the following variables: ``PROJ_FOUND`` if the library found ``PROJ_LIBRARIES`` full path to the library ``PROJ_INCLUDE_DIRS`` where to find the library headers ``PROJ_VERSION_STRING`` version string of PROJ Copyright (c) 2009 Mateusz Loskot Copyright (c) 2015 NextGIS Copyright (c) 2018 Hiroshi Miura #]=======================================================================] find_path(PROJ_INCLUDE_DIR proj.h PATHS ${PROJ_ROOT}/include DOC "Path to PROJ library include directory") set(PROJ_NAMES ${PROJ_NAMES} proj proj_i) set(PROJ_NAMES_DEBUG ${PROJ_NAMES_DEBUG} projd proj_d) if(NOT PROJ_LIBRARY) find_library(PROJ_LIBRARY_RELEASE NAMES ${PROJ_NAMES}) find_library(PROJ_LIBRARY_DEBUG NAMES ${PROJ_NAMES_DEBUG}) include(SelectLibraryConfigurations) select_library_configurations(PROJ) mark_as_advanced(PROJ_LIBRARY_RELEASE PROJ_LIBRARY_DEBUG) endif() unset(PROJ_NAMES) unset(PROJ_NAMES_DEBUG) if(PROJ_INCLUDE_DIR) file(READ "${PROJ_INCLUDE_DIR}/proj.h" PROJ_H_CONTENTS) string(REGEX REPLACE "^.*PROJ_VERSION_MAJOR +([0-9]+).*$" "\\1" PROJ_VERSION_MAJOR "${PROJ_H_CONTENTS}") string(REGEX REPLACE "^.*PROJ_VERSION_MINOR +([0-9]+).*$" "\\1" PROJ_VERSION_MINOR "${PROJ_H_CONTENTS}") string(REGEX REPLACE "^.*PROJ_VERSION_PATCH +([0-9]+).*$" "\\1" PROJ_VERSION_PATCH "${PROJ_H_CONTENTS}") unset(PROJ_H_CONTENTS) set(PROJ_VERSION_STRING "${PROJ_VERSION_MAJOR}.${PROJ_VERSION_MINOR}.${PROJ_VERSION_PATCH}") endif () include(FindPackageHandleStandardArgs) find_package_handle_standard_args(PROJ REQUIRED_VARS PROJ_LIBRARY PROJ_INCLUDE_DIR VERSION_VAR PROJ_VERSION_STRING) mark_as_advanced(PROJ_INCLUDE_DIR PROJ_LIBRARY) if(PROJ_FOUND) set(PROJ_LIBRARIES "${PROJ_LIBRARY}") set(PROJ_INCLUDE_DIRS "${PROJ_INCLUDE_DIR}") if(NOT TARGET PROJ::proj) add_library(PROJ::proj UNKNOWN IMPORTED) set_target_properties(PROJ::proj PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PROJ_INCLUDE_DIR}" IMPORTED_LINK_INTERFACE_LANGUAGES "C") if(EXISTS "${PROJ_LIBRARY}") set_target_properties(PROJ::proj PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES "C" IMPORTED_LOCATION "${PROJ_LIBRARY}") endif() if(EXISTS "${PROJ_LIBRARY_RELEASE}") set_property(TARGET PROJ::proj APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) set_target_properties(PROJ::proj PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "C" IMPORTED_LOCATION_RELEASE "${PROJ_LIBRARY_RELEASE}") endif() if(EXISTS "${PROJ_LIBRARY_DEBUG}") set_property(TARGET PROJ::proj APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG) set_target_properties(PROJ::proj PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "C" IMPORTED_LOCATION_DEBUG "${PROJ_LIBRARY_DEBUG}") endif() endif() endif() jeolib-miallib-1.1.6/cmake/modules/FindSHAPELIB.cmake000066400000000000000000000005571467232417700221400ustar00rootroot00000000000000find_path( SHAPELIB_INCLUDE_DIR shapefil.h PATH_SUFFIXES libshp ${SHAPELIB_FIND_OPTS}) find_library( SHAPELIB_LIBRARY shp ${SHAPELIB_FIND_OPTS}) include( FindPackageHandleStandardArgs ) FIND_PACKAGE_HANDLE_STANDARD_ARGS( SHAPELIB SHAPELIB_INCLUDE_DIR SHAPELIB_LIBRARY ) set(SHAPELIB_LIBRARIES ${SHAPELIB_LIBRARY} ) set(SHAPELIB_INCLUDE_DIRS ${SHAPELIB_INCLUDE_DIR} ) jeolib-miallib-1.1.6/core/000077500000000000000000000000001467232417700153375ustar00rootroot00000000000000jeolib-miallib-1.1.6/core/c/000077500000000000000000000000001467232417700155615ustar00rootroot00000000000000jeolib-miallib-1.1.6/core/c/aflood.c000066400000000000000000000310251467232417700171720ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Morphological carving \cite soille-vogt-colombo2003wrr \cite soille2004prl * @author Pierre Soille */ #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif /** \addtogroup group_dem * @{ */ #define PIX_TYPE unsigned char #define LABEL_TYPE unsigned short #define LABEL_MAX 0x7FFF /* 16383 */ /* was 0x7FFF */ #define LABEL_MSB 0x8000 IMAGE *uc_aflood(LABEL_TYPE *iml, PIX_TYPE *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ long int i, ofs, ofsk, bofs, npix; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; int k, shftk; IMAGE *imdir; UCHAR *pdir; FIFO4 *aq; PIX_TYPE *p1, *p2, minval; int ak; npix = (long int)nx*ny*nz; maxfl++; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("aflood(): not enough memory for the FAH\n"); return NULL; } /* create maxfl queues */ for (i=0; i1)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; iminval){ /* backtrack */ *(imr+bofs)=minval; bofs-=shft[pdir[bofs]]; /* printf("bactracking\n"); */ } /* discard reached minimum */ aq = create_fifo4(10); fifo4_add(aq, (long int)(iml+ofsk)); while ((p1 = (PIX_TYPE *)fifo4_remove(aq))){ for (ak=0; ak < nshft; ak++){ p2 = p1 + shft[ak]; if (*p2 == 1){ *p2 = 0; fifo4_add(aq, (long int)p2); } } } free_fifo4(aq); } *(iml+ofsk)=*(iml+ofs); } else *(iml+ofsk)=LABEL_MAX; } } } clear_fifo(pq); } free(fah); return imdir; } #undef PIX_TYPE #undef LABEL_TYPE #undef LABEL_MAX #undef LABEL_MSB #define PIX_TYPE unsigned short #define LABEL_TYPE unsigned short #define LABEL_MAX 0x7FFF /* 16383 */ /* was 0x7FFF */ #define LABEL_MSB 0x8000 IMAGE *us_aflood(LABEL_TYPE *iml, PIX_TYPE *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ #ifdef WRITETIFF char fname[13]; IMAGE im[2]; int box[6]; IMAGE *imtmp1; #endif long int i, ofs, ofsk, bofs, npix; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; int k, shftk; IMAGE *imdir; UCHAR *pdir; FIFO4 *aq; PIX_TYPE *p1, *p2, minval; int ak, crtlevel; npix = (long int)nx*ny*nz; maxfl++; #ifdef WRITETIFF im[0].p_im = (char *)iml; im[0].DataType = 5; im[0].nx = nx; im[0].ny = ny; im[0].nz = nz; im[0].NByte = (long int)nx*ny*nz*2; im[0].center = 0; im[0].vol = 0; im[0].lut = NULL; im[1].p_im = (char *)imr; im[1].DataType = 5; im[1].nx = nx; im[1].ny = ny; im[1].nz = nz; im[1].NByte = (long int)nx*ny*nz*2; im[1].center = 0; im[1].vol = 0; im[1].lut = NULL; BOX_2D; #endif /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("aflood(): not enough memory for the FAH\n"); return NULL; } /* create maxfl queues */ for (i=0; i1)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; icrtlevel){ i=crtlevel; pq=fah[crtlevel]; } fifo_add(fah[crtlevel],(long int)ofsk); pdir[ofsk]=k; if (*(iml+ofsk)==1){ /* irrelevant minima reached */ minval = *(imr+ofsk); /* elevation of minimum */ bofs=ofs; while (*(imr+bofs)>minval){ /* backtrack */ /* write_tiff(imr, "toto.tif"); */ *(imr+bofs)=minval; bofs-=shft[pdir[bofs]]; } /* discard reached minimum */ aq = create_fifo4(10); fifo4_add(aq, (long int)(iml+ofsk)); while ((p1 = (PIX_TYPE *)fifo4_remove(aq))){ for (ak=0; ak < nshft; ak++){ p2 = p1 + shft[ak]; if (*p2 == 1){ *p2 = 0; fifo4_add(aq, (long int)p2); } } } free_fifo4(aq); } *(iml+ofsk)=*(iml+ofs); } /* if (*imr+ofsk) 32767 */ #define PIX_TYPE unsigned char #define LABEL_TYPE unsigned long #define LABEL_MAX 0x7FFFFFFF #define LABEL_MSB 0x80000000 ERROR_TYPE uc_l_aflood(unsigned long *iml, unsigned char *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ long int i, ofs, ofsk, npix; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; int k, shftk; npix = (long int)nx*ny*nz; maxfl++; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("aflood(): not enough memory for the FAH\n"); return -9; } /* create maxfl queues */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i. ***********************************************************************/ /* by Pierre Soille@ec.europa.eu first: 20120218 */ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif #include "fifo.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 IMAGE *uc_alphacc(IMAGE *dissx, IMAGE *dissy, int alpha) { PIX_TYPE *pdx, *pdy, dissmax=PIX_MAX; IMAGE *ilbl; CC_LBL_TYPE *plbl, lbl=0; long int nx, ny, x, y, ofs; FIFO4 *q; int box[6]; if (alpha >= dissmax){ (void)sprintf(buf,"alphacc(): alpha must be < %d\n", dissmax); errputstr(buf); return NULL; } BOX_2D; uc_framebox(dissx, box, dissmax); uc_framebox(dissy, box, dissmax); nx=GetImNx(dissy); ny=GetImNy(dissx); ilbl=create_image(t_CC_LBL_TYPE, nx, ny, 1); if (ilbl == NULL){ (void)sprintf(buf,"alphacc(): not enough memory for label image!\n"); errputstr(buf); return NULL; } q = create_fifo4((nx*ny)/100L); if (q == NULL){ free_image(ilbl); (void)sprintf(buf,"alphacc(): not enough memory for queue!\n"); errputstr(buf); return NULL; } plbl=(CC_LBL_TYPE *)GetImPtr(ilbl); pdx=(PIX_TYPE *)GetImPtr(dissx); pdy=(PIX_TYPE *)GetImPtr(dissy); for(y=1;yg.u32_val=lbl; return ilbl; } #undef CC_LBL_TYPE #undef t_CC_LBL_TYPE #include "uc_undef.h" IMAGE *alphacc(IMAGE *dissx, IMAGE *dissy, int alpha) { /* check for possible errors */ if (szcompat(dissx, dissy) != NO_ERROR){ (void)sprintf(buf,"ERROR in alphacc(): \ images of dissimilarities of different size or type\n"); errputstr(buf); return(NULL); } switch (GetImDataType(dissx)){ case t_UCHAR: return(uc_alphacc(dissx, dissy, alpha)); break; default: (void)sprintf(buf,"alphacc(): invalid pixel type (%d)\n", GetImDataType(dissx)); errputstr(buf); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/alphatree.c000066400000000000000000000702631467232417700177020ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2012-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Computation of the tree of alpha-connected components \cite soille2008pami * @author Pierre Soille */ /* by Pierre Soille@ec.europa.eu first: 20120219 second: 20120220 */ #include #include #include #ifdef OPENMP #include #endif #include "miallib.h" #include "fifo.h" #include "pqueue.h" /** \addtogroup group_label * @{ */ /* alphacc.c */ extern IMAGE *alphacc(IMAGE *dissx, IMAGE *dissy, int alpha); /* alphatreetoCCs.c */ extern IMAGE *uc_alphatreetoCCs_OMP(IMAGE **atree, IMAGE *imblbl, IMAGE *flaglut, int rule); // first 20120219 // create hstlevel array with #level = dissim_max (assuming integer dissim values). // while initialising parent image array and DIR PQs // #level[0]=nlbl[0] // create arrays of size nlbl: parent label // Retrieve from DIR PQ /* Need to check whether the 0-CCs are properly calculated in case the dissimilarity is not a norm since we assume that the dissimilarity between ngb 0-CCs is equal */ /* 20121003 (Tag der Einheit): allow for reduced number of nodes through coefficient coeff in ]0,1] default = 1. The maximum number of nodes of an alpha-tree equals twice the number of 0-CCs minus 1. This upper-nound is seldom encountered in practice. Therefore, rather than allocating the memory for this maximal number of nodes, a multipliction coefficient in ]0,1] is introduced, its default value being equal to 1: nmax=n+n*coeff-1. This variable is useful to decrease substantially the memory needs for the computation of the tree. The optimal value of this parameter is the one leading to the exact number of components of the tree. However, this number is not known in advance. Experimental analysis may give some typical indication of adequate values. Note in addition that in the current version, the label image is of type UINT32 so that the maximal number of nodes cannot exceed this value. Note that in the present version, the number of nodes used to construct the alpha-tree is higher than the actual number of nodes of the tree. This needs to be optimised in a future version by freeing redundant nodes. In case the actual number exceeds the authorised number, the programme avoids crashing by checking whether nbelow+ncrt exceeds nmax. In this latter case, the programme should free all memory allocated so far, print an error message, and returm a NULL pointer. */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define LABEL_MSB 0x80000000 #define LABEL_BITS 0x7FFFFFFF IMAGE **uc_alphatree(IMAGE *dissx, IMAGE *dissy, int alphamax) { PIX_TYPE *pdx, *pdy, *alphalbl; IMAGE *ilbl, *iprtlbl, *ipcprtlbl, *iblbl, *ialphalbl; IMAGE *imhst; /* 20120323: for cumulative histogram of # nodes per label */ IMAGE **imap; CC_LBL_TYPE *plbl, lbl, blblp, blblq, lblp, lblq, ablbl, albl; /* p -> q (blbl for base label) */ CC_LBL_TYPE lblr; CC_LBL_TYPE n, nbelow, ncrt, nrm; long int nmax; double coeff=1.0; UINT32 *phst; /* 20120323: cumulative histogram of # nodes per label */ // CC_LBL_TYPE *corr, clbl=0; int k; long int i, nx, npix, ofs; long int shft[4], shftdissp[4], shftdissq[4], dir[4]; unsigned *prtlbl, *pcprtlbl, *blbl; int prio=0, priocrt; FIFO4 *q, *qs; /* qa queue of active nodes at current levels */ PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; nx=GetImNx(dissy); shft[0]=-1; shft[1]=1; shft[2]=-nx; shft[3]=nx; shftdissp[0]=-1; shftdissp[1]=0; shftdissp[2]=-nx; shftdissp[3]=0; shftdissq[0]=0; shftdissq[1]=1; shftdissq[2]=0; shftdissq[3]=nx; dir[0]=1; dir[1]=1; dir[2]=nx; dir[3]=nx; /* warning: for memory usage, some arrays need to be allocated further down after dissx and dissy will be freed */ printf("0-CC detection\n"); ilbl=alphacc(dissx, dissy, 0); if (ilbl == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for 0-CCs!\n"); errputstr(buf); return NULL; } n=ilbl->g.u32_val; coeff=1.0; if ( (coeff<=0.0) || (coeff>=1.0) ) nmax=2*(long int)n-1; else nmax=(long int)(n+n*coeff-1); /* let us test values of coeff. in ]0,1] : 0.5 as a 1st guess */ if (nmax!=MIN(nmax,INT32_MAX)){ printf("Maximal number (%ld) of nodes exceeds 2^32 ... resetting to 2^32\n", nmax); nmax=MIN(nmax,INT32_MAX); } printf("Maximal number of nodes=%ld\n against upper bound=%ul\n", nmax, 2*n-1); iprtlbl=create_image(t_UINT32, nmax, 1, 1); if (iprtlbl == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for parent array!\n"); errputstr(buf); free_image(ilbl); return NULL; } iblbl=create_image(t_UINT32, nmax, 1, 1); if (iblbl == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for base label array!\n"); errputstr(buf); free_image(ilbl); free_image(iprtlbl); return NULL; } ipcprtlbl=create_image(t_UINT32, n+1, 1, 1); if (ipcprtlbl == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for path compressed parent array!\n"); errputstr(buf); free_image(ilbl); free_image(iprtlbl); free_image(iblbl); return NULL; } ialphalbl=create_image(t_PIX_TYPE, nmax, 1, 1); if (ialphalbl == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for alpha lbl array!\n"); errputstr(buf); free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); return NULL; } imhst=create_image(t_UINT32, alphamax, 1, 1); if (imhst == NULL){ (void)sprintf(buf,"alphatree(): not enough memory for cumulative histogram array!\n"); errputstr(buf); free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); free_image(ialphalbl); return NULL; } pq = pqinit(NULL, GetImNPix(ilbl)/100L+1024); /* priority queue */ if (pq == NULL){ free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); free_image(ialphalbl); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); free_image(ialphalbl); free_pq(pq); return NULL; } qs = create_fifo4(65536); if (qs == NULL){ free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); free_image(ialphalbl); free_pq(pq); free_fifo4(q); return NULL; } pdx=(PIX_TYPE *)GetImPtr(dissx); /* horizontal dissimilarities */ pdy=(PIX_TYPE *)GetImPtr(dissy); /* vertical dissimilarities */ plbl=(CC_LBL_TYPE *)GetImPtr(ilbl); /* for 0-CC labelled image (defines base labels) */ prtlbl=(UINT32 *)GetImPtr(iprtlbl); /* parent label for each alpha tree node */ blbl=(UINT32 *)GetImPtr(iblbl); /* base label arrays for each alpha tree node */ pcprtlbl=(UINT32 *)GetImPtr(ipcprtlbl); /* path compressed parent label for each base label */ alphalbl=(PIX_TYPE *)GetImPtr(ialphalbl);/* level at which a node appears */ phst=(UINT32 *)GetImPtr(imhst); /* for number of nodes at each level */ npix=GetImNPix(ilbl); //dumpxyz(ilbl,0,0,0,10,10); printf("initialising priority queue\n"); /* scan 0-CCs while initialising prtlbl array for base level (from 1 to n) and the pqueue with only one link between each pair of neighbouring 0-CCs */ /* WARNING: in this initial version, we assume that the dissimilarity between ngb 0-CCs is equal */ for(i=0;ialphamax) continue; } else if(pdy[i+shftdissp[k]]>alphamax) continue; prtlbl[plbl[i+shft[k]]]=1; /* flag */ fifo4_add(qs,i+shft[k]); /* add flagged to stack */ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->offset=plbl[i+shftdissp[k]]&LABEL_BITS; //i+shftdiss[k]; if(dir[k]==1) pqd->prio=pdx[i+shftdissp[k]]; /* dissimilarity */ else pqd->prio=pdy[i+shftdissp[k]]; /* dissimilarity */ pqd->val=plbl[i+shftdissq[k]]&LABEL_BITS; /* 1 for right, nx for below */ pqmininsert(pq,pqd); /* add edge dissim to pqueue */ } } /* scan crt 0-CC */ while ((ofs = fifo4_remove(q))){ for(k=0;k<4;k++){ if(plbl[ofs+shft[k]]==lbl){ plbl[ofs+shft[k]]|=LABEL_MSB; fifo4_add(q,ofs+shft[k]); } else if (plbl[ofs+shft[k]] && (prtlbl[plbl[ofs+shft[k]]&LABEL_BITS]==0)){ if(dir[k]==1){ if(pdx[ofs+shftdissp[k]]>alphamax) continue; } else if(pdy[ofs+shftdissp[k]]>alphamax) continue; prtlbl[plbl[ofs+shft[k]]]=1; /* flag */ fifo4_add(qs,ofs+shft[k]); /* add flagged to stack */ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->offset=plbl[ofs+shftdissp[k]]&LABEL_BITS; //ofs+shftdiss[k]; if(dir[k]==1) pqd->prio=pdx[ofs+shftdissp[k]]; /* dissimilarity */ else pqd->prio=pdy[ofs+shftdissp[k]]; /* dissimilarity */ pqd->val=plbl[ofs+shftdissq[k]]&LABEL_BITS; // =dir[k]; /* 0 for right, 1 for below */ pqmininsert(pq,pqd); /* add edge dissim to pqueue */ } } } /* reset prtlbl on stack */ while ((ofs = fifo4_remove(qs))){ prtlbl[plbl[ofs]]=0; } } } printf("size of queue q after initialization=%ld\n", q->qplast-q->qp); printf("size of queue qs after initialization=%ld\n", qs->qplast-qs->qp); printf("size of priority queue pq after initialization=%u\n", pq->size); free_image(ilbl); /* copy level 0 of prtlbl in pcprtlbl */ for(i=0;iprio; ncrt=0; printf("size of storage queue before retrieving from pq=%ld\n", qs->qplast-qs->qp); printf("size of priority queue before retrieving from pq=%u\n", pq->size); printf("starting with alpha level=%d, number of nodes below=%u at previous level=%u\n", priocrt, nbelow, nbelow); phst[0]=nbelow; while (pqminremove(pq, apqd) != NULL){ blblp=apqd[0]->offset; prio=apqd[0]->prio; blblq=apqd[0]->val; free((void*) *apqd); if (prio!=priocrt){ phst[priocrt]=ncrt; priocrt=prio; if (ncrt!=0){ nbelow+=ncrt; printf("starting with alpha level=%d, number of nodes below=%u at previous level=%u\n", prio, nbelow, ncrt); if(nbelow>=nmax){ printf("The numbers of nodes below exceeds the maximum allowed number of nodes (%ld)!!!\n", nmax); free_image(ilbl); free_image(iprtlbl); free_image(iblbl); free_image(ipcprtlbl); free_image(ialphalbl); free_pq(pq); free_fifo4(q); free_fifo4(qs); return NULL; } /* path compression at previous level 20120314 */ /* still missing: remove redundant nodes by compressing labels so that no more unused labels after this pass */ nrm=0; for(i=nbelow-ncrt+1;i<=nbelow;i++){ lblp=i; while(prtlbl[lblp]!=lblp){ fifo4_add(qs,lblp); lblp=prtlbl[lblp]; nrm++; } while ((albl = fifo4_remove(qs))){ alphalbl[albl]=255; /* invalidate this redundant node */ prtlbl[albl]=lblp; pcprtlbl[blbl[albl]]=lblp; blbl[albl]=blbl[lblp]; } } /* make sure parents at previous level point directly to the root of the compressed paths */ while((albl = fifo4_remove(q))){ /* set all nodes of previous level to path compressed parents */ prtlbl[albl]=prtlbl[prtlbl[albl]]; /* before rm redun just this withour corr */ } ncrt=0; printf("number of redundant nodes (1st estimation) =%d\n", nrm); nrm=0; printf("end of dealing with previous level\n\n"); /* code hereafter was used instead but does not work: there may be several levels of redundant nodes!!! and nodes linking to current level do not necessarily originate all from previous level!!! */ /* for(i=nbelow-ncrt-ncrtm1+1;i<=nbelow-ncrt;i++){ */ /* // printf("prtlbl[%d]=%d prtlbl[prtlbl[%d]]=%d\n", i, prtlbl[i], i,prtlbl[prtlbl[i]]); */ /* if(alphalbl[prtlbl[i]]==255) */ /* printf("COUCOU\n"); */ /* prtlbl[i]=prtlbl[prtlbl[i]]; */ /* if(alphalbl[prtlbl[i]]==255) */ /* printf("GLOUP should never occur\n"); /\* should never occur!!! *\/ */ /* } */ /* ncrtm1=ncrt; */ } } //printf("find root of p\n"); lblp=pcprtlbl[blblp]; fifo4_add(qs,blblp); while(prtlbl[lblp]!=lblp){ /* find root */ //lblp=prtlbl[lblp]; // full path from pcprtlbl[blblp]: too slow lblp=pcprtlbl[blbl[prtlbl[lblp]]]; // along pc paths fifo4_add(qs,blbl[lblp]); } //printf("find root of q\n"); lblq=pcprtlbl[blblq]; fifo4_add(qs,blblq); while(prtlbl[lblq]!=lblq){ /* find root */ //lblq=prtlbl[lblq]; // full path from pcprtlbl[blblq]: too slow lblq=pcprtlbl[blbl[prtlbl[lblq]]]; // along pc paths fifo4_add(qs,blbl[lblq]); } lblr=MAX(lblp,lblq); if ((lblr<=nbelow) && (lblp!=lblq)){ /* new node discovered */ ncrt++; lbl++; prtlbl[lbl]=lbl; blbl[lbl]=MIN(blblp,blblq); alphalbl[lbl]=priocrt; lblr=lbl; } /* tried else with MIN but does not work: must always link to the newest */ if((lblp<=nbelow) && (lblp!=lblq)) fifo4_add(q,lblp); /* finally inserted only once (20120321) */ if((lblq<=nbelow) && (lblp!=lblq)) fifo4_add(q,lblq); /* finally inserted only once (20120321) */ prtlbl[lblp]=lblr; /* link to lblr */ prtlbl[lblq]=lblr; /* link to lblr */ while ((ablbl = fifo4_remove(qs))){ /* link to current root */ pcprtlbl[ablbl]=lblr; } } if (ncrt!=0){ /* this happens if cc appears at the highest dissimilarity level! 20120418 */ printf("%d nodes appeared at the maximum dissimilarity=%d!\n", ncrt,priocrt); phst[priocrt]=ncrt; nbelow+=ncrt; printf("starting with alpha level=%d, number of nodes below=%u at previous level=%u\n", prio, nbelow, ncrt); /* path compression at previous level 20120314 */ /* still missing: remove redundant nodes by compressing labels so that no more unused labels after this pass */ nrm=0; for(i=nbelow-ncrt+1;i<=nbelow;i++){ lblp=i; while(prtlbl[lblp]!=lblp){ fifo4_add(qs,lblp); lblp=prtlbl[lblp]; nrm++; } while ((albl = fifo4_remove(qs))){ alphalbl[albl]=255; /* invalidate this redundant node */ prtlbl[albl]=lblp; pcprtlbl[blbl[albl]]=lblp; blbl[albl]=blbl[lblp]; } } /* make sure parents at previous level point directly to the root of the compressed paths */ while((albl = fifo4_remove(q))){ /* set all nodes of previous level to path compressed parents */ prtlbl[albl]=prtlbl[prtlbl[albl]]; /* before rm redun just this withour corr */ } printf("number of redundant nodes (1st estimation)=%d\n", nrm); printf("end of dealing with previous level\n\n"); } printf("size of priority queue after retrieving from pq=%u\n", pq->size); printf("available size of priority queue after retrieving from pq=%u\n", pq->avail); printf("size of storage queue before freeing it=%ld\n", qs->qplast-qs->qp); printf("freeing qs queue\n"); free_fifo4(q); free_fifo4(qs); printf("freeing priority queue\n"); free_pq(pq); //free_image(iblbl); //free_image(iprtlbl); //free_image(ipcprtlbl); nbelow+=ncrt; /* total number of nodes */ printf("total number of nodes in tree=%u \n", nbelow); prtlbl=(CC_LBL_TYPE *)realloc((void *)prtlbl, sizeof(CC_LBL_TYPE)*(nbelow+1)); blbl=(CC_LBL_TYPE *)realloc((void *)blbl, sizeof(CC_LBL_TYPE)*(nbelow+1)); alphalbl=(PIX_TYPE *)realloc((void *)alphalbl, sizeof(PIX_TYPE)*(nbelow+1)); SetImNx(iprtlbl, nbelow+1); SetImNx(iblbl, nbelow+1); SetImNx(ialphalbl, nbelow+1); printf("setting image array pointers\n"); imap=(IMAGE **)calloc(sizeof(IMAGE *), 5); imap[0]=iprtlbl; imap[1]=iblbl; imap[2]=ipcprtlbl; imap[3]=ialphalbl; imap[4]=imhst; return imap; } #undef CC_LBL_TYPE #undef t_CC_LBL_TYPE #undef LABEL_MSB #undef LABEL_BITS #include "uc_undef.h" IMAGE **alphatree(IMAGE *dissx, IMAGE *dissy, int alphamax) { /* check for possible errors */ if (szcompat(dissx, dissy) != NO_ERROR){ (void)sprintf(buf,"ERROR in alphatree(): \ images of dissimilarities of different size or type\n"); errputstr(buf); return(NULL); } switch (GetImDataType(dissx)){ case t_UCHAR: return(uc_alphatree(dissx, dissy, alphamax)); break; default: (void)sprintf(buf,"alphatree(): invalid pixel type (%d)\n", GetImDataType(dissx)); errputstr(buf); } return(NULL); } #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define LABEL_MSB 0x80000000 #define LABEL_BITS 0x7FFFFFFF IMAGE *uc_alphatreeincattr(IMAGE **atree, IMAGE **attr0cc, int type) { // GLOUP: accumulation on the last label!!! IMAGE *iattr; MIALFLOAT *pattr, *pattr0cc; CC_LBL_TYPE lbl, *prtlbl; unsigned long n=GetImNx(atree[0]); unsigned long nbase=GetImNx(atree[2]); if (type==3){ iattr=create_image(t_FLOAT, GetImNx(atree[0]), 1, 4); } else iattr=create_image(t_FLOAT, GetImNx(atree[0]), 1, 1); if (iattr == NULL){ (void)sprintf(buf,"alphatreeincattr(): not enough memory for iattr!\n"); errputstr(buf); return NULL; } pattr=(MIALFLOAT *)GetImPtr(iattr); prtlbl=(CC_LBL_TYPE* )GetImPtr(atree[0]); switch (type){ case 0: /* minimum value */ f_blank(iattr, MIALFLOAT_MAX); pattr[0]=0.0; pattr0cc=(MIALFLOAT *)GetImPtr(attr0cc[0]); #ifdef OPENMP #pragma omp parallel for #endif for(lbl=1;lbl0;i--). Inially a bottom-up approach was considered for(i=1;i0;i--){ if (pflut[i]){ #ifdef OPENMPX q = create_fifo4(4096L); #endif lbl=pflut[i]; //prtlbl=prtlbl[i]; blbl=pblbl[i]; ofs=pofs[blbl]; pout[ofs]=lbl; alphacrt=palphalbl[i]; //printf("i=%d lbl=%u blbl=%u ofs=%u alphacrt=%d\n", i, lbl, blbl, ofs, alphacrt); fifo4_add(q,ofs); while ((ofs = fifo4_remove(q))){ for(k=0;k<4;k++){ ofsk=ofs+shft[k]; if(pout[ofsk]==0){ lblofsk=pimblbl[ofsk]; if(lblofsk==pimblbl[ofs]){ pout[ofsk]=lbl; fifo4_add(q,ofsk); } else if(lblofsk){ //printf("lblofsk=%u prtlbl[lblofsk]=%u\n", lblofsk, prtlbl[lblofsk]); while(prtlbl[lblofsk]!=i){ lblofsk=prtlbl[lblofsk]; if(palphalbl[lblofsk]>alphacrt) break; if(prtlbl[lblofsk]==lblofsk){ printf("GLOUP lblofsk=%u prtlbl[lblofsk]=%u alphacrt=%d ofs=%d ofsk=%d \n", lblofsk, prtlbl[lblofsk], alphacrt, ofs, ofsk); break; } } if(prtlbl[lblofsk]==i){ //printf("COMMON ROOT\n"); pout[ofsk]=lbl; fifo4_add(q,ofsk); } } } } } #ifdef OPENMPX free_fifo4(q); #endif } } #ifndef OPENMPX free_fifo4(q); #endif return imout; } #undef CC_LBL_TYPE #undef t_CC_LBL_TYPE #undef LABEL_MSB #undef LABEL_BITS #include "uc_undef.h" IMAGE *alphatreetoCCs(IMAGE **atree, IMAGE *imblbl, IMAGE *flaglut, int rule) { switch (GetImDataType(atree[3])){ case t_UCHAR: return(uc_alphatreetoCCs_OMP(atree, imblbl, flaglut, rule)); break; default: (void)sprintf(buf,"alphatreetoccs(): invalid pixel type (%d)\n", GetImDataType(atree[3])); errputstr(buf); } return(NULL); } #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define LABEL_MSB 0x80000000 #define LABEL_BITS 0x7FFFFFFF IMAGE *uc_alphatreenextlevel(IMAGE **atree, IMAGE *crtprtlbl, int alpha) { // first: 20120301 IMAGE *lut; CC_LBL_TYPE *prtlbl, *pcrtprtlbl, *plut; // *pblbl PIX_TYPE *palphalbl; unsigned long nbase=GetImNx(atree[2]); unsigned long int i; /* output is lut with label value of each CC appearing at level alpha */ lut=create_image(t_CC_LBL_TYPE, nbase, 1, 1); if (lut == NULL){ (void)sprintf(buf,"alphatreenextlevel(): not enough memory for lut!\n"); errputstr(buf); return NULL; } pcrtprtlbl=(CC_LBL_TYPE* )GetImPtr(crtprtlbl); /* current parent label */ prtlbl=(CC_LBL_TYPE* )GetImPtr(atree[0]); // pblbl=(CC_LBL_TYPE* )GetImPtr(atree[1]); palphalbl=(PIX_TYPE* )GetImPtr(atree[3]); plut=(CC_LBL_TYPE *)GetImPtr(lut); /* if(palphalbl[pcrtprtlbl[i]]alpha) */ /* break; */ /* pcrtprtlbl[i]=prtlbl[pcrtprtlbl[i]]; */ /* if(pcrtprtlbl[i]==prtlbl[pcrtprtlbl[i]]) /\* root reached *\/ */ /* break; */ /* } */ if(palphalbl[pcrtprtlbl[i]]==alpha){ //plut[i]=pblbl[pcrtprtlbl[i]]; // keep base label plut[i]=pcrtprtlbl[i]; /* set to node label */ pcrtprtlbl[i]=prtlbl[pcrtprtlbl[i]]; } } return lut; } #undef CC_LBL_TYPE #undef t_CC_LBL_TYPE #undef LABEL_MSB #undef LABEL_BITS #include "uc_undef.h" IMAGE *alphatreenextlevel(IMAGE **atree, IMAGE *crtprtlabel, int alpha) { switch (GetImDataType(atree[3])){ case t_UCHAR: return(uc_alphatreenextlevel(atree, crtprtlabel, alpha)); break; default: (void)sprintf(buf,"alphatreenextlevel(): invalid pixel type (%d)\n", GetImDataType(atree[3])); errputstr(buf); } return(NULL); } #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 IMAGE *uc_alphatreepersistencelut(IMAGE **atree) { // first: 20120301 IMAGE *lut; CC_LBL_TYPE *prtlbl; PIX_TYPE *palphalbl, *plut; unsigned long n=GetImNx(atree[0]); unsigned long int i; /* output is lut with persistence value of each CC */ lut=create_image(t_PIX_TYPE, n, 1, 1); if (lut == NULL){ (void)sprintf(buf,"alphatreepersistencelut(): not enough memory for lut!\n"); errputstr(buf); return NULL; } prtlbl=(CC_LBL_TYPE* )GetImPtr(atree[0]); palphalbl=(PIX_TYPE* )GetImPtr(atree[3]); plut=(PIX_TYPE *)GetImPtr(lut); /* here we go */ #ifdef OPENMP #pragma omp parallel for #endif for(i=1;i. ***********************************************************************/ /* by Pierre Soille@ec.europa.eu version with optimisation of distribution of load through correspondence table. However, the load remains unbalanced if the size of the target CCs is uneven! */ #include #include #include #ifdef OPENMP #include #endif #include "miallib.h" #include "fifo.h" #include "pqueue.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define LABEL_MSB 0x80000000 #define LABEL_BITS 0x7FFFFFFF IMAGE *uc_alphatreetoCCs_OMP(IMAGE **atree, IMAGE *imblbl, IMAGE *flaglut, int rule) { // first: 20120301 /* this routine is meant for extracting CCs matching non-increasing attributes (in this latter case use *alphatreeincattr). The rule adopted here (20120319) is to go down in the tree from top and reconstruct each CC flagged with 1: for(i=n-1;i>0;i--). Inially a bottom-up approach was considered for(i=1;i0;i--){ for(j=alphamax;j>=0;j--){ ncrt=hst[j]; //printf("j=%d ncrt=%d ", j, ncrt); #ifdef OPENMP // parallelization should occur alpha level by alpha level starting from top #pragma omp parallel for private(l,i,q,lbl,blbl,ofs,alphacrt,k,ofsk,lblofsk) #endif for(l=1;l<=ncrt;l++){ i=ncumcrt-l; if (pflut[i] && (pout[pofs[pblbl[i]]]==0)){ #ifdef OPENMP q = create_fifo4(65536L); #endif lbl=pflut[i]; blbl=pblbl[i]; ofs=pofs[blbl]; pout[ofs]=lbl; alphacrt=palphalbl[i]; //printf("i=%d lbl=%u blbl=%u ofs=%u alphacrt=%d\n", i, lbl, blbl, ofs, alphacrt); fifo4_add(q,ofs); while ((ofs = fifo4_remove(q))){ for(k=0;k<4;k++){ ofsk=ofs+shft[k]; if(pout[ofsk]==0){ lblofsk=pimblbl[ofsk]; if(lblofsk==pimblbl[ofs]){ pout[ofsk]=lbl; fifo4_add(q,ofsk); } else if(lblofsk){ //printf("lblofsk=%u prtlbl[lblofsk]=%u\n", lblofsk, prtlbl[lblofsk]); while(prtlbl[lblofsk]!=i){ lblofsk=prtlbl[lblofsk]; if(palphalbl[lblofsk]>alphacrt) break; if(prtlbl[lblofsk]==lblofsk){ // This can in fact happen if the top node is in lut!!! // printf("GLOUP lblofsk=%u prtlbl[lblofsk]=%u alphacrt=%d ofs=%d ofsk=%d palphalbl[lblofsk]=%d\n", lblofsk, prtlbl[lblofsk], alphacrt, ofs, ofsk, (int)palphalbl[lblofsk]); break; } } if(prtlbl[lblofsk]==i){ /* common root */ pout[ofsk]=lbl; fifo4_add(q,ofsk); } } } } } #ifdef OPENMP free_fifo4(q); #endif } } ncumcrt-=ncrt; } #ifndef OPENMP free_fifo4(q); #endif return imout; } #undef CC_LBL_TYPE #undef t_CC_LBL_TYPE #undef LABEL_MSB #undef LABEL_BITS #include "uc_undef.h" /*@}*/ jeolib-miallib-1.1.6/core/c/b_def.h000066400000000000000000000020141467232417700167660ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* definitions for t_ONEBITPERPIXEL type */ #define FLOATING 0 #define SIGNED 0 #define OVFL_TEST 0 #define PIX_TYPE INT #define PIX_MIN INT_MIN #define PIX_MAX INT_MAX jeolib-miallib-1.1.6/core/c/b_undef.h000066400000000000000000000017541467232417700173430ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* undefinitions for t_ONEBITPERPIXEL type */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX jeolib-miallib-1.1.6/core/c/base.h000066400000000000000000000026351467232417700166520ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** base.h - description ------------------- begin : Tue Apr 13 2004 ***************************************************************************/ #ifndef init_base #define init_base #include "miallib.h" #define SEED 0x04 #define NOSEED 0x00 #define BORDER 0x01 #define IN_NHQ 0x02 #define IN_PQ 0x03 #define NOTLABELED 0x00 #define LABELED 0x01 // labels are or larger than this value #endif jeolib-miallib-1.1.6/core/c/borderdetection.c000066400000000000000000000703371467232417700211130ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** borderdetection.c - description ------------------- border detection algorithm for detecting the exact boundary lines of the region begin : Thu May 13 2004 ***************************************************************************/ #include #include #define NO_BUF #include "borderdetection.h" #include "miallib.h" #include "base.h" /* * initLine: initialize line * * Parameters: * * line pointer to line * * n initial size of points the line can store. * * Return values: * * NULL if line parameter was NULL, or if points could not be allocated * * line same pointer as input line; if everything is ok * */ struct LINE *initLine(struct LINE *line, int n) { if (line==NULL){ return NULL; } if ((line->points = calloc(sizeof(struct POINT *), n))==NULL){ return NULL; } line->size = line->step = n; line->crtPos = 0; return line; } /* * arePointsEqual: checks whether the poits have the same x and y values * * Parameters: * * point1 first point * * point2 second point * * Return values: * * 0 if values of the two points are different * * 1 if values of the two lines are equal * */ int arePointsEqual(struct POINT * point1, struct POINT * point2) { if((point1->x ==point2->x) && (point1->y == point2->y)){ return 1; } else{ return 0; } } /* * isLineSegmentClosed: checks whether the line is closed or not * (checks whether coordinates of start and end point are the same) * * Parameters: * * line line * * Return values: * * 0 if line is not closed * * 1 if line is closed * */ int isLineSegmentClosed(struct LINE * line) { struct POINT * firstPoint, *lastPoint; if(line->crtPos==1){ return 0; } firstPoint = line->points[0]; lastPoint = line->points[line->crtPos-1]; if(arePointsEqual(firstPoint, lastPoint)){ return 1; }else{ return 0; } } /* * getLineSegment: returns 2 LINES of a region, which have the (with the attributes) * specified 2 points as start and end point * * Parameters: * * region region with line segments * * pointSearch1 first point * * pointSearch2 second point * * Return values: * * Pointer two 2 LINE-pointer. If 2 lines were found by algorithm, both are non-NULL pointer. If only * one line was found, the second pointer in the return line pointer array is NULL. * */ struct LINE **getLineSegment(struct REGION * region, struct POINT * pointSearch1, struct POINT * pointSearch2) { int i,j=0; struct LINE * line; struct LINE ** returnLine; struct POINT * point1, * point2; returnLine=calloc(2, sizeof(struct LINE *)); returnLine[0]=NULL; returnLine[1]=NULL; for(i=0; icrtPos; i++){ line = region->lines[i]; point1=line->points[0]; point2=line->points[line->crtPos-1]; if((arePointsEqual(pointSearch1, point1) && arePointsEqual(pointSearch2, point2)) || (arePointsEqual(pointSearch2, point1) && arePointsEqual(pointSearch1, point2))){ returnLine[j++]=line; } } return returnLine; } /* * getNextPoint: returns next point of the boundary of a region. * * Parameters: * * region region with line segments * * point the following point to this point is seeked * * trace stores the line segments which should not be used for this lookup any more. * * Return values: * * NULL if no further point was found any more * * point pointer to a point, if a point was found */ struct POINT *getNextPoint(struct REGION * region, struct POINT * point, int * trace) { int i; struct LINE * crtLine; struct POINT * point1, * point2; for(i=region->crtPos-1; i>=0; i--){ crtLine=region->lines[i]; //if line has only one point => not proper line=> not ready yet => return NULL if(crtLine->crtPos<2){ return NULL; } point1 =crtLine->points[0]; point2 = crtLine->points[crtLine->crtPos-1]; if(point1!=point && point2!=point && !arePointsEqual(point1, point2)){ if(trace[i]==0){ if(arePointsEqual(point1, point)){ trace[i]=1; return point2; } if(arePointsEqual(point2, point)){ trace[i]=1; return point1; } } } } return NULL; } /* * isRegionClosed: checks whether region boundary is closed or not. * * Parameters: * * region region with line segments * * Return values: * * 0 if boundary of region is not closed * * 1 if boundary if region is closed */ int isRegionClosed(struct REGION *region) { int i, * trace; struct POINT * firstPoint=NULL, * tmpPoint; struct LINE * firstLine; trace = (int *)calloc(sizeof(int), region->crtPos); for(i=0; icrtPos; i++){ trace[i]=0; } if((region->crtPos)>0){ if(region->isFirstLineSegmentClosed){ //if(isLineSegmentClosed(region->lines[0])){ free(trace); return 1; } firstLine=region->lines[0]; trace[0]=1; firstPoint=firstLine->points[0]; if(firstLine->crtPos==1){ free(trace); return 0; } tmpPoint=getNextPoint(region, firstPoint, trace); if(tmpPoint==NULL){ free(trace); return 0; } while(!arePointsEqual(firstPoint, tmpPoint)){ tmpPoint = getNextPoint(region, tmpPoint, trace); if(tmpPoint==NULL){ free(trace); return 0; } } free(trace); return 1; } free(trace); return 0; } /* * freeLine: frees the memory allocated for the line * * Parameters: * * line pointer to line * * Return values: * * none */ void freeLine(struct LINE * line) { int i; struct POINT ** points; if(line==NULL){ return; } points = line->points; for(i=0; icrtPos; i++){ free(points[i]); } free(points); } /* * freeRegion: frees the memory allocated for the region * * Parameters: * * region pointer to region * * Return values: * * none */ void freeRegion(struct REGION * region) { int i; struct LINE ** lines; if(region==NULL){ return; } lines = region->lines; for(i=0; icrtPos; i++){ freeLine(lines[i]); } free(region->colorValues); free(region->lines); } /* * addLineToRegion: add line to region * * Parameters: * * region pointer to region * * line pointer to line which shall be added to region * * Return values: * * NULL if region or line was NULL, or if line could not be added * * region pointer to region, if line was added */ struct REGION *addLineToRegion(struct REGION * region, struct LINE * line) { printf("add Line to Region\n"); int newSize, crtPos; struct LINE ** tmpLines; if(!region || !line){ return NULL; } if(region->size == region->crtPos){ newSize = region->size + region->step; if((tmpLines = realloc(region->lines, sizeof(struct LINE *) * newSize))==NULL){ return NULL; } region->lines=tmpLines; region->size=newSize; } tmpLines = region->lines; crtPos = region->crtPos; tmpLines[crtPos++]=line; region->crtPos=crtPos; return region; } /* * replaceLastLineOfRegion: replaces last line of region (and deletes the replaced region) * * Parameters: * * region pointer to region * * line pointer to line which shall be added to region * * Return values: * * NO_ERROR if last line was replaced * * ERROR if error occured */ ERROR_TYPE replaceLastLineOfRegion(struct REGION * region, struct LINE * newLine) { struct LINE * oldLine; if(region->crtPos>0){ oldLine = region->lines[region->crtPos-1]; region->lines[region->crtPos-1]=newLine; freeLine(oldLine); free(oldLine); return NO_ERROR; } return ERROR; } /* * addPointToLine: adds the point to the line. If line has not enough space any more, * it is automatically resized * * Parameters: * * line pointer to line * * point pointer to point which shall be added to line * * Return values: * * NULL if line or point was NULL, and if point could not be added to line. * * line pointer to line to which point was added */ struct LINE *addPointToLine(struct LINE * line, struct POINT * point) { int newSize, crtPos; struct POINT ** tmpPoints, ** newPoints; if(!line || !point){ return NULL; } if((line->size) == line->crtPos){ newSize = line->size + line->step; if(!(newPoints = realloc(line->points, sizeof(struct POINT *) * newSize))){ return NULL; } line->points=newPoints; line->size=newSize; } tmpPoints = line->points; crtPos = line->crtPos; tmpPoints[crtPos++]=point; line->crtPos=crtPos; return line; } /* * initRegion: initializes region * * Parameters: * * region pointer to region * * lineSize initial size of lines, the region can store. * * pointSize initial size of point, a line of the region can store. * * channelSize size of channels, the region must be able to handel. * * Return values: * * NULL if an error occured * * region pointer to initialzed region, if everything was ok. * */ struct REGION *initRegion(struct REGION * region, int lineSize, int pointSize, int channelSize) { struct LINE ** lines; int * colorValues; if((lines=calloc(lineSize, sizeof(struct LINE *)))==NULL){ printf("Not enough memory - initRegion()!!!\n"); return NULL; } if((colorValues=calloc(channelSize, sizeof(int)))==NULL){ return NULL; } region->colorValues=colorValues; region->channelSize=channelSize; region->size = region->step = lineSize; region->crtPos = 0; region->lines = lines; region->isFirstLineSegmentClosed=0; return region; } /* * setUseFlags: set the use flags of all points of the lines in the linepool to a * with the attribute specified value. * * Parameters: * * linepool pointer to linepool * * value value to which the use-flag of the point shall be set * * Return values: * * none */ void setUseFlags(struct LINEPOOL * linepool, int value) { int i,j; struct LINE * line; struct POINT * point; int pointCount; for(i=0; i< linepool->crtPos; i++){ line = linepool->lines[i]; pointCount = line->crtPos; for(j=0; jpoints[j]; point->useFlag=value; } } } /* * correctCoordinateValue: make a correction of all coordinate values of the * points of the lines in the linepool. * * Parameters: * * linepool pointer to linepool * * correctX value with which the x coordinates shall be corrected * * correctY value with which the y coordinates shall be corrected * * Return values: * * none */ void correctCoordinateValues(struct LINEPOOL * linepool, int correctX, int correctY) { int i,j; struct LINE * line; struct POINT * point; int pointCount; for(i=0; i< linepool->crtPos; i++){ line = linepool->lines[i]; pointCount = line->crtPos; for(j=0; jpoints[j]; point->x=point->x+correctX; point->y=point->y+correctY; } } } /* * savePixel: adds a point to the line whereas the pixels are calculated by the value of the attributes * * Parameters: * * oldDir old direction of the snake * * newDir new direction of the snake * * pixX current x position of snake * * pixY current y position of snake * * line line to which point shall be added * * Return values: * * NO_ERROR if no error occured * * ERROR if error occured */ ERROR_TYPE savePixel(int oldDir, int newDir, USHORT pixX, USHORT pixY, struct LINE * line) { struct POINT * point; int i=0; if(!line){ return ERROR; } if((point = malloc(sizeof(struct POINT)))==NULL){ printf("Not enough memory - savePixel()!!!"); return ERROR; } //calculate the point which shall be stored in the line if(oldDir == NORTH){ if(newDir==LEFT){ point->x=pixX; point->y=pixY+1; i=1; }else if (newDir == RIGHT){ point->x=pixX; point->y=pixY; i=1; }else if (newDir == STRAIGHT){ point->x=pixX; point->y=pixY+1; i=1; } }else if(oldDir == EAST){ if(newDir==LEFT){ point->x=pixX; point->y=pixY; i=1; }else if (newDir == RIGHT){ point->x=pixX+1; point->y=pixY; i=1; }else if(newDir == STRAIGHT){ point->x=pixX; point->y=pixY; i=1; } }else if(oldDir == SOUTH){ if(newDir==LEFT){ point->x=pixX+1; point->y=pixY; i=1; }else if (newDir == RIGHT){ point->x=pixX+1; point->y=pixY+1; i=1; }else if (newDir == STRAIGHT){ point->x=pixX+1; point->y=pixY; i=1; } }else if(oldDir == WEST){ if(newDir==LEFT){ point->x=pixX+1; point->y=pixY+1; i=1; }else if (newDir == RIGHT){ point->x=pixX; point->y=pixY+1; i=1; }else if (newDir == STRAIGHT){ point->x=pixX+1; point->y=pixY+1; i=1; } } if(i==1){ if(addPointToLine(line, point)==NULL){ return ERROR; } }else{ free(point); } return NO_ERROR; } /* * getNextOffset: returns the next offset value in the image according to the values of the attributes * * Parameters: * * im pointer to image * * oldDir old direction of the snake * * newDir new direction of the snake * * point resulting offset is stored here as x and y coordinates * * Return values: * * offset number */ long int getNextOffset(IMAGE * im, int oldDir, int newDir, struct POINT * point) { int nx; nx = GetImNx(im); if(oldDir==NORTH){ if(newDir==LEFT){ if(point !=NULL){ point->x=-1; point->y=0; } return -1; }else if(newDir==STRAIGHT){ if(point !=NULL){ point->x=0; point->y=-1; } return -nx; }else if(newDir==RIGHT){ if(point !=NULL){ point->x=1; point->y=0; } return 1; }else if(newDir==DIAGONALBACK){ if(point !=NULL){ point->x=-1; point->y=1; } return nx-1; }else{ if(point !=NULL){ point->x=0; point->y=0; } return 0; } }else if(oldDir==EAST){ if(newDir==LEFT){ if(point !=NULL){ point->x=0; point->y=-1; } return -nx; }else if(newDir==STRAIGHT){ if(point !=NULL){ point->x=1; point->y=0; } return +1; }else if(newDir==RIGHT){ if(point !=NULL){ point->x=0; point->y=1; } return +nx; }else if(newDir==DIAGONALBACK){ if(point !=NULL){ point->x=-1; point->y=-1; } return -nx-1; }else{ if(point !=NULL){ point->x=0; point->y=0; } return 0; } }else if(oldDir==SOUTH){ if(newDir==LEFT){ if(point !=NULL){ point->x=1; point->y=0; } return 1; }else if(newDir==STRAIGHT){ if(point !=NULL){ point->x=0; point->y=1; } return +nx; }else if(newDir==RIGHT){ if(point !=NULL){ point->x=-1; point->y=0; } return -1; }else if(newDir==DIAGONALBACK){ if(point !=NULL){ point->x=1; point->y=-1; } return -nx+1; }else{ if(point !=NULL){ point->x=0; point->y=0; } return 0; } }else if(oldDir==WEST){ if(newDir==LEFT){ if(point !=NULL){ point->x=0; point->y=1; } return nx; }else if(newDir==STRAIGHT){ if(point !=NULL){ point->x=-1; point->y=0; } return -1; }else if(newDir==RIGHT){ if(point !=NULL){ point->x=0; point->y=-1; } return -nx; }else if(newDir==DIAGONALBACK){ if(point !=NULL){ point->x=1; point->y=+1; } return nx+1; }else{ if(point !=NULL){ point->x=0; point->y=0; } return 0; } } if(point !=NULL){ point->x=0; point->y=0; } return 0; } /* * calculateNewDir: calculates the new direction of the snake. * * Parameters: * * oldDir old direction of the snake * * newDir new direction of the snake * * point resulting offset is stored here as x and y coordinates * * Return values: * * 0 if direction is not possible (snake can never go back) * * DIRECTION if it is a valid direction */ int calculateNewDir(int oldDir, int newDir){ if(oldDir==NORTH){ if(newDir==LEFT){ return WEST; }else if(newDir==STRAIGHT){ return NORTH; }else if(newDir==RIGHT){ return EAST; }else return 0; }else if (oldDir==EAST){ if(newDir==LEFT){ return NORTH; }else if(newDir==STRAIGHT){ return EAST; }else if(newDir==RIGHT){ return SOUTH; }else return 0; }else if(oldDir==SOUTH){ if(newDir==LEFT){ return EAST; }else if(newDir==STRAIGHT){ return SOUTH; }else if(newDir==RIGHT){ return WEST; }else return 0; }else if(oldDir==WEST){ if(newDir==LEFT){ return SOUTH; }else if(newDir==STRAIGHT){ return WEST; }else if(newDir==RIGHT){ return NORTH; }else return 0; }else return 0; } /* * detectBorders: border detection algorithm for the detection of the exact boundary * lines of the regions of the segmented image. * * Parameters: * * inputIm input label image * * regions array of regions * * regionNumber number of elements in regions-array * * linepool pointer to linepool * * Return values: * * NO_ERROR if boundaries were detected properly * * ERROR if there was an error */ ERROR_TYPE detectBorders(IMAGE * inputIm, struct REGION ** regions, int regionNumber, struct LINEPOOL * linepool) { int isFirstLine=0; LBL_TYPE * pIm; IMAGE * statusIm; UCHAR * pStatusIm; int nx, ny, x,y,oldDir, newDir, crtX, crtY; long int crtOffset, newOffset, crtLabel=-1, oldNeighbourLabel, newNeighbourLabel, lastOffset; long int shft[8]; struct POINT coordinates, *point, * startPoint, * endPoint, * middlePoint; struct LINE * crtLine, * tmpLine; int box[6]; box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; printf("detectBorders() - start to detect borders\n"); // check whether image has datatype unsigned long int if (GetImDataType(inputIm) != t_LBL_TYPE){ return ERROR; } if (u32_addframebox(inputIm, box, BORDER) == ERROR){ return ERROR; } nx = GetImNx(inputIm); ny = GetImNy(inputIm); pIm = (LBL_TYPE *) GetImPtr(inputIm); statusIm = (IMAGE *) create_image(t_UCHAR,nx,ny,1); pStatusIm=(UCHAR *) GetImPtr(statusIm); if (set_seq_shift(GetImNx(inputIm), GetImNy(inputIm), GetImNz(inputIm), 4, shft) == ERROR){ return ERROR; } write_tiff(inputIm, "label_borderdetection.tif"); for(y=0; yx=x; point->y=y; if(addPointToLine(crtLine, point)==NULL){ return ERROR; } pStatusIm[crtOffset]=LABELED; while(!isRegionClosed(regions[crtLabel])){ newOffset = getNextOffset(inputIm, oldDir, LEFT, &coordinates); if(pIm[crtOffset+newOffset]==crtLabel && ((crtOffset+newOffset)!=lastOffset)){ newDir=LEFT; }else{ newOffset = getNextOffset(inputIm, oldDir, STRAIGHT, &coordinates); if(pIm[crtOffset+newOffset]==crtLabel){ newDir=STRAIGHT; }else{ newOffset = getNextOffset(inputIm, oldDir, RIGHT, &coordinates); newDir=RIGHT; } } //if you turn left or right you must save the point if(newDir==RIGHT || newDir==LEFT){ if(savePixel(oldDir, newDir,crtX, crtY, crtLine)==ERROR){ return ERROR; } oldDir=calculateNewDir(oldDir, newDir); }else if(newDir==STRAIGHT){ lastOffset=crtOffset; crtOffset+=newOffset; crtX+=coordinates.x; crtY+=coordinates.y; pStatusIm[crtOffset]=LABELED; } else return ERROR; //if first line is closed (=> region has only one line), add it to region if(isFirstLine==1){ if(isLineSegmentClosed(crtLine)){ addLineToRegion(regions[crtLabel], crtLine); regions[crtLabel]->isFirstLineSegmentClosed=1; addLineToLinePool(linepool, crtLine); isFirstLine=0; break; } } //make postprocess - finish line segment if neighbour changes //get the label of the neighbour region (left pixel in walking direction) newNeighbourLabel=pIm[crtOffset+getNextOffset(inputIm, oldDir,LEFT,NULL)]; if((newNeighbourLabel!=oldNeighbourLabel && newNeighbourLabel!=crtLabel)|| (newDir!=STRAIGHT && oldNeighbourLabel==newNeighbourLabel && oldNeighbourLabel!=pIm[crtOffset+getNextOffset(inputIm, oldDir, DIAGONALBACK, NULL)])){ // if((newNeighbourLabel!=oldNeighbourLabel && newNeighbourLabel!=crtLabel)){ //if last step was going straight, the last point was not saved. Do this here if(newDir==STRAIGHT){ if(savePixel(oldDir, newDir,crtX, crtY, crtLine)==ERROR){ return ERROR; } } // make lookup whether this linesegment already exists in linepool //if yes, take from linesegment from linepool and add this to region //if no, add to current linesegment to line pool and to region //save last point if(!(point=malloc(sizeof(struct POINT)))){ printf("No memory left - detectBorders()"); return ERROR; } point->x=crtLine->points[crtLine->crtPos-1]->x; point->y=crtLine->points[crtLine->crtPos-1]->y; if(isFirstLine){ free(crtLine); isFirstLine=0; }else{ //have a look whether linesegment already exists in linepool startPoint = crtLine->points[0]; endPoint = crtLine->points[crtLine->crtPos-1]; if(crtLine->crtPos>2){ //take middle point of line middlePoint = crtLine->points[((crtLine->crtPos)-1)/2]; tmpLine = getLine(linepool, startPoint->x, startPoint->y, middlePoint->x, middlePoint->y, endPoint->x, endPoint->y); if(tmpLine!=NULL){ printf("found linesegment in pool - replace it !!!\n"); replaceLastLineOfRegion(regions[crtLabel], tmpLine); if(isLineSegmentClosed(tmpLine)){ //if the line already exist in linepool and if it is closed, then the region is closed as well, //and the algorithm needs to go on with the next region. //delete last line segment of region (but do not free it)!!! regions[crtLabel]->crtPos=regions[crtLabel]->crtPos-1; break; } }else{ printf("didn't find linesegment in pool - add it!!!\n"); addLineToLinePool(linepool, crtLine); } }else{ tmpLine = getLineWith2Points(linepool, startPoint->x, startPoint->y, endPoint->x,endPoint->y); if(tmpLine!=NULL){ replaceLastLineOfRegion(regions[crtLabel], tmpLine); }else{ addLineToLinePool(linepool, crtLine); } } } oldNeighbourLabel=newNeighbourLabel; if(!isRegionClosed(regions[crtLabel])){ //save last point printf("newLinesegment!!!\n"); if((crtLine = (malloc(sizeof(struct LINE))))==NULL){ printf("No memory left - detectBorders()"); return ERROR; } initLine(crtLine, 100); if(addPointToLine(crtLine, point)==NULL){ return ERROR; } //add line segment to current region and to neighbour region if(addLineToRegion(regions[crtLabel], crtLine)==NULL){ return ERROR; } } } } } } } } correctCoordinateValues(linepool, -1, -1); subframebox(inputIm, box); return NO_ERROR; } /*************************************************************************** writeShapeFile.h - description ------------------- begin : Thu May 27 2004 ***************************************************************************/ #ifndef init_writeShapeFile #define init_writeShapeFile #include "borderdetection.h" #include #include extern ERROR_TYPE writeShapeFile(struct REGION ** regions, int regionNumber, char * fileName); extern SHPObject * writeSHPPolygon(struct REGION * region, int id, GTIF * gtif); #endif /*************************************************************************** writeSVG.h - description ------------------- begin : Fri May 14 2004 ***************************************************************************/ #ifndef init_writeSVG #define init_writeSVG #include "borderdetection.h" #include #include extern ERROR_TYPE writeSVGPolygon(struct REGION * region, gzFile fhd, GTIF *gtif); extern ERROR_TYPE writeSVG(struct REGION ** regions, int regionNumber, char * fileName, int width, int height); #endif jeolib-miallib-1.1.6/core/c/borderdetection.h000066400000000000000000000065171467232417700211170ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** borderdetection.h - description ------------------- begin : Thu May 13 2004 ***************************************************************************/ #ifndef init_borderdetection #define init_borderdetection #include "miallib.h" #include #include #define NORTH 0x01 #define EAST 0x02 #define SOUTH 0x03 #define WEST 0x04 #define LEFT 0x05 #define RIGHT 0x06 #define STRAIGHT 0x07 #define DIAGONALBACK 0x08 struct LINEPOOL{ int size, crtPos, step; struct LINE ** lines; }; struct POINT { int x; int y; int useFlag; }; struct LINE { int size, crtPos, step; struct POINT ** points; }; struct REGION { int size, crtPos, step; struct LINE ** lines; int * colorValues; int channelSize; int isFirstLineSegmentClosed; }; struct LINE * initLine(struct LINE *line, int n); int isRegionClosed(struct REGION *region); int isLineSegmentClosed(struct LINE * line); void freeLine(struct LINE * line); void freeRegion(struct REGION * region); struct REGION * addLineToRegion(struct REGION * region, struct LINE * line); struct LINE * addPointToLine(struct LINE * line, struct POINT * point); struct REGION * initRegion(struct REGION * region, int lineSize, int pointSize, int channelSize); ERROR_TYPE savePixel(int oldDir, int newDir, USHORT pixX, USHORT pixY, struct LINE * line); long int getNextOffset(IMAGE * im, int oldDir, int newDir, struct POINT * point); ERROR_TYPE detectBorders(IMAGE * inputIm, struct REGION ** regions, int regionNumber, struct LINEPOOL * linepool); struct LINEPOOL * initLinePool(struct LINEPOOL * linepool, int size); struct LINE * getLine(struct LINEPOOL * linepool, int startX, int startY, int middleX, int middleY, int endX, int endY); struct LINE * getLineWith2Points(struct LINEPOOL * linepool, int startX, int startY, int endX, int endY); struct LINEPOOL * addLineToLinePool(struct LINEPOOL * linepool, struct LINE * line); void freeLinePool(struct LINEPOOL * linepool); struct POINT * getNextPoint(struct REGION * region, struct POINT * point, int * trace); int arePointsEqual(struct POINT * point1, struct POINT * point2); struct LINE ** getLineSegment(struct REGION * region, struct POINT * pointSearch1, struct POINT * pointSearch2); void setUseFlags(struct LINEPOOL * linepool, int value); void correctCoordinateValues(struct LINEPOOL * linepool, int correctX, int correctY); #endif jeolib-miallib-1.1.6/core/c/bresenham.c000066400000000000000000000223121467232417700176710ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" /** @addtogroup group_geom * @{ */ void bresenham(int x1, int y1, int x2, int y2, long int pb[], double delta[], int rlc[], int ncol) { /* starting from http://www.geocities.com/ResearchTriangle/Lab/1767/pol.html#g_bresline but using the direct implementation with non-integer calculations (why bother in our case!) */ long int dx, dy, adx, ady, sx, sy, x, y, xold, yold; double a, b; dx = x2 - x1; dy = y2 - y1; adx = abs(dx); /* We're comparing lengths, so we must take the */ ady = abs(dy); /* absolute value to ensure correct decisions. */ sx = SGN(dx); /* The sign of the delta values tell us if we need to*/ sy = SGN(dy); /* add or subtract 1 to traverse the axes of the line.*/ x = x1; y = y1; yold=y1; xold=x1; *rlc=1; *pb++=(long int)x1+y1*(long int)ncol; /* shifts in image from image origin */ *delta++=0; if (adx>ady){ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ do{ x = x + sx; /* Move along the 'long' axis */ y = (long int)(a*x+b+0.5*sy); /* (int)(a*x+b+0.5*sy); */ *delta++ = y-(a*x+b); if (y==yold) *rlc +=1; else{ rlc++; *rlc=1; } yold=y; *pb++ = x+y*ncol; } while (x!=x2); } else{ a=(double)dx/dy; /* slope of line */ b=(double)x1-a*y1; /* offset of line at origin */ do{ y = y + sy; /* ;Move along the 'long' axis */ x = (long int)(a*y+b+0.5); *delta++ = (a*y+b)-x; if (x==xold) *rlc +=1; else{ rlc++; *rlc=1; } xold=x; *pb++ = x+y*ncol; } while (y!=y2); } } void tracelinecorrect(int x1, int y1, int x2, int y2, long int pb[], int rlc[], int ncol, int nx) { long int dx, dy, adx, ady, sx, sy, x, y, xold, yold; double a, b; dx = x2 - x1; dy = y2 - y1; adx = abs(dx); /* We're comparing lengths, so we must take the */ ady = abs(dy); /* absolute value to ensure correct decisions. */ sx = SGN(dx); /* The sign of the delta values tell us if we need to*/ sy = SGN(dy); /* add or subtract 1 to traverse the axes of the line.*/ x = x1; y = y1; yold=y1; xold=x1; *rlc=1; *pb++=(long int)x1+y1*(long int)ncol; /* shifts in image from image origin */ if (adx>=ady){ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ do{ x = x + sx; /* Move along the 'long' axis */ y = (long int)(a*x+b+sy*0.5); /* 20120430: added sy!!! */ if (y==yold) *rlc +=1; else{ rlc++; *rlc=1; } yold=y; *pb++ = x+y*ncol; } while (abs(x-x1)!=nx-1); } else{ a=(double)dx/dy; /* slope of line */ b=(double)x1-a*y1; /* offset of line at origin */ do{ y = y + sy; /* Move along the 'long' axis */ x = (long int)(a*y+b+0.5); if (x==xold) *rlc +=1; else{ rlc++; *rlc=1; } xold=x; *pb++ = x+y*ncol; } while (abs(y-y1)!=nx-1); } } #include "uc_def.h" ERROR_TYPE uc_plotline(IMAGE *im, int x1, int y1, int x2, int y2, int val) { int dx, dy, adx, ady, sx, sy, x, y; double a, b; PIX_TYPE *pim; long int ncol, nlin, nx; pim = (PIX_TYPE *)GetImPtr(im); ncol =GetImNx(im); nlin =GetImNy(im); if ( (x1>=ncol) || (x2>=ncol) || (y1>=nlin) || (y2>=nlin) ){ (void)sprintf(buf,"ERROR_TYPE plotline(): coordinates outside image frame\n"); errputstr(buf); return(ERROR); } dx = x2 - x1; dy = y2 - y1; adx = abs(dx); /* We're comparing lengths, so we must take the */ ady = abs(dy); /* absolute value to ensure correct decisions. */ nx = MAX(adx,ady); sx = SGN(dx); /* The sign of the delta values tell us if we need to*/ sy = SGN(dy); /* add or subtract 1 to traverse the axes of the line.*/ x = x1; y = y1; *(pim+x1+y1*ncol)=val; /* shifts in image from image origin */ if( (dx==dy) && (dx==0) ) return (NO_ERROR); if (adx==ady){ /* no rounding */ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ do{ x = x + sx; /* Move along the 'long' axis */ y = (int)(a*x+b); *(pim+x+y*ncol)=val; } while (abs(x-x1)!=nx); } else if (adx>ady){ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ do{ x = x + sx; /* Move along the 'long' axis */ /*OLD y = (int)(a*x+b+0.5*sy); */ y = (int)(a*x+b+0.5); *(pim+x+y*ncol)=val; } while (abs(x-x1)!=nx); } else{ a=(double)dx/dy; /* slope of line */ b=(double)x1-a*y1; /* offset of line at origin */ do{ y = y + sy; /* Move along the 'long' axis */ /*OLD x = (int)(a*y+b+0.5*sx); */ x = (int)(a*y+b+0.5); *(pim+x+y*ncol)=val; } while (abs(y-y1)!=nx); } return (NO_ERROR); } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_plotline(IMAGE *im, int x1, int y1, int x2, int y2, int val) { long int dx, dy, adx, ady, sx, sy, x, y, i; double a, b; long int ncol, nlin; PIX_TYPE *pim; pim=(PIX_TYPE *) GetImPtr(im); ncol=GetImNx(im); nlin=GetImNy(im); if ( (x1>=ncol) || (x2>=ncol) || (y1>=nlin) || (y2>=nlin) ){ (void)sprintf(buf,"ERROR_TYPE plotline(): coordinates outside image frame\n"); errputstr(buf); return(ERROR); } dx = x2 - x1; dy = y2 - y1; adx = abs(dx); /* We're comparing lengths, so we must take the */ ady = abs(dy); /* absolute value to ensure correct decisions. */ sx = SGN(dx); /* The sign of the delta values tell us if we need to*/ sy = SGN(dy); /* add or subtract 1 to traverse the axes of the line.*/ x = x1; y = y1; *(pim+x1+y1*ncol)=(PIX_TYPE)val; /* shifts in image from image origin */ if( (dx==dy) && (dx==0) ) return (NO_ERROR); if (adx>=ady){ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ for (i=0; i=ncol) || (x2>=ncol) || (y1>=nlin) || (y2>=nlin) ){ (void)sprintf(buf,"ERROR_TYPE plotline(): coordinates outside image frame\n"); errputstr(buf); return(ERROR); } dx = x2 - x1; dy = y2 - y1; adx = abs(dx); /* We're comparing lengths, so we must take the */ ady = abs(dy); /* absolute value to ensure correct decisions. */ sx = SGN(dx); /* The sign of the delta values tell us if we need to*/ sy = SGN(dy); /* add or subtract 1 to traverse the axes of the line.*/ x = x1; y = y1; *(pim+x1+y1*ncol)=(PIX_TYPE)val; /* shifts in image from image origin */ if( (dx==dy) && (dx==0) ) return (NO_ERROR); if (adx>=ady){ a=(double)dy/dx; /* slope of line */ b=(double)y1-a*x1; /* offset of line at origin */ for (i=0; i. ***********************************************************************/ /* define BYTE_ORDER for BIG_ and LITTLE_ENDIAN architectures */ /* #if defined(__i386__) || defined(__i486__) || defined(__alpha__) || defined(__TURBOC__)\ */ /* || (defined(__mips__) && (defined(MIPSEL) || defined (__MIPSEL__))) */ /* #define BYTE_ORDER 1234 */ /* #elif defined(__mc68000__) || defined (__sparc__) \ */ /* || (defined(__mips__) && (defined(MIPSEB) || defined (__MIPSEB__))) */ /* #define BYTE_ORDER 4321 */ /* #else */ /* #error architecture not supported by the Linux C library */ /* #endif */ jeolib-miallib-1.1.6/core/c/ced.c000066400000000000000000000144051467232417700164640ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2005-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "fifo.h" #ifdef OPENMP #include #endif /** \addtogroup group_dist * @{ */ /* ** 'Optimised' Bresenham's algorithm used in ced function. */ int inmaskp(IMAGE *buf_n, long int offset_r, long int x2, long int y2) { /* ** buf_n : I(UCHAR) ** x1 y1 : coordinates of first point ** x2 y2 : coordinates of second point */ long int d, dx, dy, s1, s2, incr1, incr2, x, y, temp, der; long int *pp; UCHAR *p = (UCHAR *)GetImPtr(buf_n) + offset_r; int interchange = TRUE; long int ncol = GetImNx(buf_n); dx = abs(x2); dy = abs(y2); s1 = SGN(x2); s2 = SGN(y2); if (dy > dx) MYSWAP(dx, dy, temp); else interchange = FALSE; d = 2 * dy - dx; incr1 = 2 * dy; incr2 = 2 * (dy - dx); x = y = 0; der = dx; pp = &x; if (interchange) pp = &y; while (abs(*pp) < der) { if (interchange) y += s2; else x += s1; if (d < 0) d += incr1; else { d += incr2; if (interchange) x += s1; else y += s2; } if (*(p + x + y * ncol) == 0){ return FALSE; } } return TRUE; } #define INQUEUE 2 #define FICTITIOUS -1 #define DXY_TYPE SHORT #define t_DXY_TYPE t_SHORT IMAGE *ced(IMAGE *ref, IMAGE *mask) { /* ** authors: Pierre Soille (c) 1991 ** IMAGE *ref: binary UCHAR image with reference pixels set to 1 ** IMAGE *mask: binary UCHAR image with geodesic mask pixels set to 1 ** comment: rewritten on Oct. 11 2005 [1.5 days] ** added DXY_TYPE and set it to SHORT on 20130902 (was fixed to INT32 before) ** so that the equivalent of 1 4-byte image is saved ** ! to_ushort needs to be changed internally if DXY_TYPE changes ! */ IMAGE *imx, *imy, *imb; UCHAR *pr, *pm; float dp, dcrt, *pb, dmin; int nx, graph=4, k, dx[8], dy[8], base_flag; long int i, npix, shft[27], ofs, ofsk; DXY_TYPE *px, *py; int box[6]; FIFO4 *q=NULL; BOX_2D; if ( (GetImDataType(ref)!=t_UCHAR) || (GetImDataType(mask)!=t_UCHAR) ){ (void)sprintf(buf, "ERROR in ced(): \ both the ref and mask images must be of type t_UCHAR\n"); errputstr(buf); return NULL; } if (graph == 4){ dx[0] = 0; dy[0] = 1; dx[1] = 1; dy[1] = 0; dx[2] = 0; dy[2] = -1; dx[3] = -1; dy[3] = 0; } else if (graph == 8){ dx[0] = 0; dy[0] = 1; dx[1] = 1; dy[1] = 0; dx[2] = 0; dy[2] = -1; dx[3] = -1; dy[3] = 0; printf("incomplete set for dx and dy when graph equals 8\n"); } generic_addframebox(ref,box,0); generic_addframebox(mask,box,0); set_seq_shift(GetImNx(ref), GetImNy(ref), GetImNz(ref), graph, shft); nx = GetImNx(ref); npix=GetImNPix(ref); q = create_fifo4((npix)/100L+1024); if (q == NULL){ return NULL; } /* init queue */ pr = (UCHAR *)GetImPtr(ref); pm = (UCHAR *)GetImPtr(mask); for (i=0;i dp) dmin = dp; } while( (ofs=fifo4_remove(q)) != FICTITIOUS ){ if (sqrt((double)(SQ((INT64)px[ofs]) + SQ((INT64)py[ofs]))) + pb[ofs] > dmin){ fifo4_add(q,ofs); /* px[ofs] = INT32_MAX; */ } else{ for (k = 0; k < graph; ++k){ ofsk=ofs+shft[k]; if (pm[ofsk] == 1){ fifo4_add(q,ofsk); pm[ofsk]=INQUEUE; } } } } } #ifdef OPENMP #pragma omp parallel for #endif for (i=0;i. ***********************************************************************/ #include #include #include #include "miallib.h" /** \addtogroup group_stat * @{ */ /* classification procedures from february 2005 last modification by Marcin Iwanowski on 17.08.05 then by Pierre Soille 20160727 for : - some cleaning - typeless calls - uc_imst -> uc_classstatsinfo Still a lot of room for cleaning ... and type checks of inputs Probably complete rewrite needed. */ INT32 *getoffsetmatrix(int offset, int number) { int i; INT32 *outpmat; if ((outpmat = (INT32 *)calloc((size_t)number,sizeof(INT32))) == NULL) return NULL; for (i=0;i1) for (i=1; i indmax) indmax = *(pla + i); invind = (int *)calloc((size_t)(indmax + 1),sizeof(int)); if (invind == NULL) { (void)sprintf(buf,"meanclasses: not enough memory\n"); errputstr(buf); free_image(meanv); return(NULL); } for (i=0; i1) for (i=1; i indmax) indmax = *(pla + i); invind = (int *)calloc((size_t)(indmax + 1),sizeof(int)); if (invind == NULL) { (void)sprintf(buf,"stddevclasses: not enough memory\n"); errputstr(buf); free_image(stddev); return(NULL); } for (i=0; i 1) *(pstddev + i*planenum + j) = sqrt (*(pstddev + i*planenum + j) / (double) (*(pla + i + clnum) - 1)); free(npix_o); free(planenum_o); free(invind); return stddev; } #include "uc_undef.h" IMAGE *stddevclasses(IMAGE *imin, IMAGE *immos, IMAGE *labels, IMAGE *meanv) { if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"error in stddevclasses(): multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return NULL; } if ( GetImDataType(immos) != GetImDataType(imin) ){ (void)sprintf(buf,"error in stddevclasses(): imin and immos must have the same data type\n"); errputstr(buf); return NULL; } switch (GetImDataType(imin)){ case t_UCHAR: return(uc_stddevclasses(imin, immos, labels, meanv)); break; default: (void)sprintf(buf,"stddevclasses(): invalid pixel type\n"); errputstr(buf); return(NULL); } } #include "uc_def.h" IMAGE *uc_minmaxclasses(IMAGE *imin, IMAGE *immos, IMAGE *labels) { /* finds the minimum and maximum value in 'imin' for every class from 'immos' */ long int npix=GetImNPix(immos); IMAGE *minmaxv; PIX_TYPE *pminmaxv; int clnum = GetImNx(labels); /* number of classes and bands */ PIX_TYPE *pmo = (PIX_TYPE *)GetImPtr(immos); PIX_TYPE *pms = (PIX_TYPE *)GetImPtr(imin); int planenum = GetImNz(imin); INT32 clplnum = clnum * planenum ; long int i,j,class; int indmax; int *invind; INT32 *npix_o, *planenum_o; INT32 *pla = (INT32 *)GetImPtr(labels); /* minmaxv - matrix of min and max values */ minmaxv = create_image (t_PIX_TYPE, planenum, clnum, 2); if (minmaxv == NULL) { (void)sprintf(buf,"minmaxclasses: not enough memory\n"); errputstr(buf); return(NULL); } pminmaxv = (PIX_TYPE *)GetImPtr(minmaxv); /* invind - matrix indicating the indexes of every label in 'labels' matrix */ indmax = *pla; if (clnum>1) for (i=1; i indmax) indmax = *(pla + i); invind = (int *)calloc((size_t)(indmax + 1),sizeof(int)); if (invind == NULL) { (void)sprintf(buf,"minmaxclasses: not enough memory\n"); errputstr(buf); free_image(minmaxv); return(NULL); } for (i=0; i (PIX_TYPE)*((pms + i) + *(npix_o + j)) ) *(pminmaxv + *(planenum_o + class) + j + clplnum) = (PIX_TYPE)*((pms + i) + *(npix_o + j)); } } free(npix_o); free(planenum_o); free(invind); return minmaxv; } #include "uc_undef.h" IMAGE *minmaxclasses(IMAGE *imin, IMAGE *immos, IMAGE *labels) { if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"error in minmaxclasses(): multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return NULL; } if ( GetImDataType(immos) != GetImDataType(imin) ){ (void)sprintf(buf,"error in minmaxclasses(): imin and immos must have the same data type\n"); errputstr(buf); return NULL; } switch (GetImDataType(imin)){ case t_UCHAR: return(uc_minmaxclasses(imin, immos, labels)); break; default: (void)sprintf(buf,"minmaxclasses(): invalid pixel type\n"); errputstr(buf); return(NULL); } } #include "uc_def.h" IMAGE *uc_parpipboundaries(IMAGE *imin, IMAGE *immos, IMAGE *labels, IMAGE *stddev, IMAGE *meanv, double mult) { /* computes boundaries for parallelpiped classifier min/max of the boundary = mean val +/- mult * standart deviation */ IMAGE *minmaxv; PIX_TYPE *pminmaxv; DOUBLE *pmeanv = (DOUBLE *)GetImPtr(meanv); DOUBLE *pstddev = (DOUBLE *)GetImPtr(stddev); int clnum = GetImNx(labels); /* number of classes and bands */ int planenum = GetImNz(imin); int i,j; int indmax; int *invind; INT32 *pla = (INT32 *)GetImPtr(labels); /* if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return ERROR; } if ( (GetImDataType(immos) != t_UCHAR) || (GetImDataType(imin) != t_UCHAR) ) { (void)sprintf(buf,"wrong input data type !! \n"); errputstr(buf); return ERROR; } */ /* minmaxv - matrix of min and max values */ minmaxv = create_image (t_PIX_TYPE, planenum, clnum, 2); if (minmaxv == NULL) { (void)sprintf(buf,"parpipboundaries: not enough memory\n"); errputstr(buf); return(NULL); } pminmaxv = (PIX_TYPE *)GetImPtr(minmaxv); /* invind - matrix indicating the indexes of every label in 'labels' matrix */ indmax = *pla; if (clnum>1) for (i=1; i indmax) indmax = *(pla + i); invind = (int *)calloc((size_t)(indmax + 1),sizeof(int)); if (invind == NULL) { (void)sprintf(buf,"parpipboundaries: not enough memory\n"); errputstr(buf); free_image(minmaxv); return(NULL); } for (i=0; i1) for (i=1; i indmax) indmax = *(pla + i); invind = (int *)calloc((size_t)(indmax + 1),sizeof(int)); if (invind == NULL) { (void)sprintf(buf,"covmatrices: not enough memory\n"); errputstr(buf); free_image(cov); return(NULL); } diffvect = (DOUBLE *) calloc ((size_t) planenum, (unsigned) sizeof(DOUBLE)); if (diffvect == NULL) { (void)sprintf(buf,"covmatrices: not enough memory\n"); errputstr(buf); free(invind); free_image(cov); return(NULL); } for (i=0; i 1) *(pcov + *(planenum2_o + i)+ j) /= (double) ((*(pla + i + clnum)) - 1); free(npix_o); free(invind); free(diffvect); return cov; } #include "uc_undef.h" IMAGE *covmatrices(IMAGE *imin, IMAGE *immos, IMAGE *meanv, IMAGE *labels) { if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"error in covmatrices(): multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return NULL; } if ( GetImDataType(immos) != GetImDataType(imin) ){ (void)sprintf(buf,"error in covmatrices(): imin and immos must have the same data type\n"); errputstr(buf); return NULL; } switch (GetImDataType(imin)){ case t_UCHAR: return(uc_covmatrices(imin, immos, meanv, labels)); break; default: (void)sprintf(buf,"covmatrices(): invalid pixel type\n"); errputstr(buf); return(NULL); } } #include "uc_def.h" IMAGE *uc_meanvals(IMAGE *imin) { /* produces a vector of mean values of bands of the image (without considering classes) */ IMAGE *meanv; DOUBLE *pmeanv; PIX_TYPE *pms = (PIX_TYPE *)GetImPtr(imin); int planenum = GetImNz(imin); long int npix = GetImNx(imin) * GetImNy(imin); long int i,j; INT32 *npix_o; /* meanv - matrix of mean values */ meanv = create_image (t_DOUBLE, planenum, 1, 1); if (meanv == NULL) { (void)sprintf(buf,"meanvals: not enough memory\n"); errputstr(buf); return(NULL); } pmeanv = (DOUBLE *)GetImPtr(meanv); for (i=0; i1 - region of inseparability) */ int classind=0; /* indexof region to which clasified pixels belong */ int inclass ; int indbklabel ; /* index of background label */ PIX_TYPE *pms = (PIX_TYPE *)GetImPtr(imin); PIX_TYPE *pmo = (PIX_TYPE *)GetImPtr(immos); int planenum = GetImNz(imin); INT32 plclnum; if ((labels = numclasses(immos)) == NULL) return ERROR; pla = (INT32 *)GetImPtr(labels); clnum = GetImNx(labels); plclnum = clnum * planenum ; printf ("parallelpiped classifier with boundaries computed as %s \n", ((mode & 1) == 0 ? "min/max values" : "mean +/- multiplied standard deviation")); printf ("number of classes: %d \n", clnum); printf ("number of planes: %d \n", planenum); if ((mode & 1) == 0) /* mode == 0 , 2 ,4 */ { if ((minmaxv = minmaxclasses(imin, immos, labels)) == NULL){free_image(labels); return ERROR;} pminmaxv = (PIX_TYPE *)GetImPtr(minmaxv); } else /* (mode & 1) == 1 => mode = 1 , 3 , 5 */ { /* computes mean values, standerd deviations and then boundaries */ if ((meanv = meanclasses (imin, immos, labels)) == NULL){free_image(labels); return ERROR;} if ((stddev = stddevclasses (imin, immos, labels, meanv)) == NULL){free_image(labels); free_image(meanv); return ERROR;} if ((minmaxv = parpipboundaries (imin, immos, labels, stddev, meanv, mult)) == NULL) {free_image(labels); free_image(meanv); free_image(stddev); return ERROR;} pminmaxv = (PIX_TYPE *)GetImPtr(minmaxv); } /* find index of background class */ indbklabel = -1 ; /* in case the background label doesn't exist on the input mosaic image - all labels are than used for classification */ for (i=0; i= (*(pminmaxv + *(planenum_o + j) + k)) ) || ((*(pms + i + *(npix_o + k))) <= (*(pminmaxv + *(planenum_o + j) + k + plclnum)) ) ) inclass = 0; if (inclass == 1){nummatcl++ ; classind = j;} } *(pmo + i) = ( ((mode & 4) == 4) ? nummatcl : ( ((mode & 2) == 2) ? (nummatcl == 1 ? *(pla + classind) : bklabel) : (nummatcl > 0 ? *(pla + classind) : bklabel))); /* set output value */ /* if the inseparability regions have to be detected three cases should be considered above: == 0 - no class; == 1 - one class (OK); >1 - more classes (inseparability region) */ } if ((mode&1)==1){free_image(meanv); free_image(stddev);} free(npix_o); free(planenum_o); free_image(minmaxv); free_image(labels); return NO_ERROR; } #include "uc_undef.h" ERROR_TYPE clparpip(IMAGE *immos, IMAGE *imin, int bklabel, int mode, double mult) { if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"error in clmindist(): multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return ERROR; } if ( GetImDataType(immos) != GetImDataType(imin) ) { (void)sprintf(buf,"error in clmindist(): imin and immos must have the same data type\n"); errputstr(buf); return ERROR; } if (GetImNz(immos) != 1) { (void)sprintf(buf,"mosaic image has more than one plane !! \n"); errputstr(buf); return ERROR; } switch (GetImDataType(imin)){ case t_UCHAR: return(uc_clparpip(immos, imin, bklabel, mode, mult)); break; default: (void)sprintf(buf,"clparpip(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(ERROR); } DOUBLE mgetpix(DOUBLE *imptr, int x, int y, int plane, int size) { /* returns value of (x,y) of a sqare matrix from plane 'plane' of a matrix notation i.e. first point is (1,1) */ return (*(imptr + ( x - 1 ) + ( y - 1 ) * size + plane * size * size)); } void msetpix (DOUBLE *imptr, int x, int y, int plane, int size, DOUBLE val) { /* sets value of pixel (x,y) of a square matrix from plane 'plane' of a matrix notation i.e. first point is (1,1) */ *(imptr + ( x - 1 ) + ( y - 1 ) * size + plane * size * size) = val; } void printmat(DOUBLE *img, int pnum, int msize) { int i,j,k; for (i=0;i big) big=temp; if (big == 0.0) { (void)sprintf(buf,"Singular matrix in routine LUDCMP\n"); errputstr(buf); return(ERROR); } vv[i]=1.0/big; } for (j=1;j<=msize;j++){ for (i=1;i= big){ big=dum; imax=i; } } if (j != imax) { for (k=1;k<=msize;k++) { dum = mgetpix(img, imax, k, pnum, msize); msetpix(img, imax, k, pnum, msize, mgetpix(img, j, k, pnum, msize)); msetpix(img, j, k, pnum, msize, dum); } *d = -(*d); vv[imax]=vv[j]; } indx[j]=imax; if (mgetpix(img,j,j,pnum,msize) == 0.0) msetpix(img,j,j,pnum,msize, 1.0e-20 ); if (j != msize){ dum=1.0/(mgetpix (img, j, j, pnum, msize)); for (i=j+1;i<=msize;i++) msetpix(img, i, j, pnum, msize, mgetpix(img, i, j, pnum, msize) * dum); } } for (i=1;i<=msize;i++) (*d)*=mgetpix(img, i, i, pnum, msize); /* determinant calculation */ for (j2=1; j2<=msize; j2++) { for (i=1;i<=msize;i++) col[i]=0.0; col[j2]=1.0; /* start lubksb */ ii = 0; for (i=1;i<=msize;i++){ ip=indx[i]; sum=col[ip]; col[ip]=col[i]; if (ii) for (j=ii;j<=i-1;j++) sum -= mgetpix(img, i, j, pnum, msize)*col[j]; else if (sum) ii=i; col[i]=sum; } for (i=msize;i>=1;i--){ sum=col[i]; for (j=i+1;j<=msize;j++) sum -= mgetpix(img, i, j, pnum, msize) * col[j]; col[i]=sum / mgetpix(img, i, i, pnum, msize); } /* end lubksb */ for (i=1;i<=msize;i++) msetpix(imgout, i, j2, outpnum, msize, col[i]); } free(indx); free(col); free(vv); return NO_ERROR ; } void mulmatrix(int size, DOUBLE *m1, int p1, DOUBLE *m2, int p2, DOUBLE *mout, int pout) { int i,j,k; DOUBLE sum; for (i=1; i<=size; i++) for (j=1; j<=size; j++) { sum = 0.0; for (k=1; k<=size; k++) sum += mgetpix (m1,i,k,p1,size) * mgetpix (m2,k,j,p2,size); msetpix (mout,i,j,pout,size,sum); } } void copymatrix(int size, DOUBLE *msrc, int psrc, DOUBLE *mdst, int pdst) { int i,j; for (i=1;i<=size;i++) for (j=1;j<=size;j++) msetpix(mdst,i,j,pdst,size,mgetpix(msrc,i,j,psrc,size)); } IMAGE *invcovmat(IMAGE *imin, DOUBLE* det) { int i; IMAGE *tmp,*out; DOUBLE *ptmp,*pout; int planenum = GetImNx(imin); int clnum = GetImNz(imin); tmp = copy_image(imin); ptmp = (DOUBLE *)GetImPtr(tmp); out = copy_image(imin); pout = (DOUBLE *)GetImPtr(out); if ((tmp == NULL) || (out == NULL)) { (void)sprintf(buf,"invconmat: not enough memory\n"); errputstr(buf); return(NULL); } for (i=0;i maxdiscr){maxdiscr = discrval; maxclass = j;} } *(pmo + i) = ( (((type&4) == 0) || (maxdiscr > thr)) ? *(pla + maxclass) : bklabel ) ; /* set output value */ } free(npix_o); free(planenum_o); free(planenum2_o); free(det); free(tmpvect); free_image(meanv); free_image(mcov); free_image(mcovinv); free_image(labels); return NO_ERROR; } #include "uc_undef.h" ERROR_TYPE clmaxlike(IMAGE *immos, IMAGE *imin, int bklabel, int type, double thr) { if ( (GetImNx(immos) != GetImNx(imin)) || (GetImNy(immos) != GetImNy(imin)) ) { (void)sprintf(buf,"error in clmaxlike(): multiband and mosaic images have different x and/or y - sizes !! \n"); errputstr(buf); return ERROR; } if ( GetImDataType(immos) != GetImDataType(imin) ) { (void)sprintf(buf,"error in clmaxlike(): imin and immos must have the same data type\n"); errputstr(buf); return ERROR; } if (GetImNz(immos) != 1) { (void)sprintf(buf,"mosaic image has more than one plane !! \n"); errputstr(buf); return ERROR; } switch (GetImDataType(imin)){ case t_UCHAR: return(uc_clmaxlike(immos, imin, bklabel, type, thr)); break; default: (void)sprintf(buf,"clmaxlike(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(ERROR); } /**@}*/ jeolib-miallib-1.1.6/core/c/colconv.c000066400000000000000000000265511467232417700174010ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" extern ERROR_TYPE szcompat(IMAGE *, IMAGE *); /** \addtogroup group_format * @{ */ /* based on \cite[pp. 235--237]{gonzalez-woods92}: @Book{gonzalez-woods92, author = "R.~Gonzalez and R.~Woods", title = "Digital image processing", publisher = "Addison-Wesley", year = 1992, address = "Reading, MA", edition = "3rd" } */ void hsi2rgb(double *h, double *s, double *i) { /* ** author: P. Soille ** double *h: hue value in [0,1] ** double *s: saturation value in [0,1] ** double *i: intensity value in [0,1] ** comment: at the end of the procedure, the variables h,s, and i hold the red, green, and blues values respectively all in the range [0,1]. Make sure that h,s, and i are in the range [0,1] before calling this function. */ double r, g, b, cmax, fac; if (*h * 360.0 <= 120.0){ /* RG sector */ b=(1- *s)/3.0; r=(1 + *s * cos(*h * 2*PI) / cos((1.0/6.0 - *h) * 2*PI))/3.0; g=1-(r+b); } else if (*h * 360.0 <= 240.0){ /* GB sector */ r=(1- *s)/3.0; *h = *h - 2.0/6.0; g=(1 + *s * cos(*h * 2*PI) / cos((1.0/6.0 - *h) * 2*PI))/3.0; b=1-(r+g); } else{ /* BR sector */ g=(1- *s)/3.0; *h = *h - 4.0/6.0; b=(1 + *s * cos(*h * 2*PI) / cos((1.0/6.0 - *h) * 2*PI))/3.0; r=1-(g+b); } /* printf("r=%f\n", (float)r); printf("g=%f\n", (float)g); printf("b=%f\n", (float)b); */ cmax=MAX(r,MAX(g,b)); fac=*i/cmax; r*= fac; g*= fac; b*= fac; /*printf("h=%f\n", (float)*h); printf("i=%f\n", (float)*i); printf("s=%f\n", (float)*s); printf("r=%f\n", (float)r); printf("g=%f\n", (float)g); printf("b=%f\n", (float)b);*/ *h=r; *s=g; *i=b; } #include "g_def.h" IMAGE *generic_imhsi2rgb(IMAGE *imh, IMAGE *ims, IMAGE *imi) { double h, s, i; mia_size_t k, npix; IMAGE *imout; PIX_TYPE *pimh, *pims, *pimi, *pout; imout = (IMAGE *)create_image(t_RGB, GetImNx(imh), GetImNy(imh), 1); if (imout == NULL){ (void)sprintf(buf,"generic_imhsi2rgb(): not enough memory!\n"); errputstr(buf); return(imout); } pout=(PIX_TYPE *)GetImPtr(imout); pimh=(PIX_TYPE *)GetImPtr(imh); pims=(PIX_TYPE *)GetImPtr(ims); pimi=(PIX_TYPE *)GetImPtr(imi); npix=GetImNx(imh)*GetImNy(imh); for (k=0; kpg[i]) minval=pg[i]; if (maxvalpb[i]) minval=pb[i]; if (maxval==minval) aph=0.0; else if (maxval==pr[i]) aph=60.0*(((double)pg[i]-(double)pb[i])/(double)(maxval-minval)); else if (maxval==pg[i]) aph=60.0*(2.0 + ((double)pb[i]-(double)pr[i])/(double)(maxval-minval)); else aph=60.0*(4.0+((double)pr[i]-(double)pg[i])/(double)(maxval-minval)); if (aph<0.0) aph+=360.0; ph[i]=(HUE_TYPE)(aph+0.5); if (type==0){ /* HSV */ if (maxval==0) aps=0.0; else aps=(double)(maxval-minval)/(double)maxval; ps[i]=(SATURATION_TYPE)(aps*PIX_MAX+0.5); pv[i]=maxval; } else if (type==1){ /* HSL */ if (maxval==0 || minval==1) aps=0.0; else aps=(double)(maxval-minval)/(double)(PIX_MAX-((double)maxval+(double)minval-PIX_MAX)); ps[i]=(SATURATION_TYPE)(aps*PIX_MAX+0.5); pv[i]=(VALUE_TYPE)(((double)maxval+(double)minval)/2.0); } else{ /* HSI */ if (pv[i]==0) aps=0.0; else aps=1.0-(double)minval/(double)pv[i]; ps[i]=(SATURATION_TYPE)(aps*PIX_MAX+0.5); pv[i]=(VALUE_TYPE)(((double)pr[i]+(double)pg[i]+(double)pb[i])/3.0); } } return(imap); } #undef t_HUE #undef t_SATURATION #undef t_VALUE #undef HUE_TYPE #undef SATURATION_TYPE #undef VALUE_TYPE #include "uc_undef.h" IMAGE **imrgb2hsx(IMAGE *imr, IMAGE *img, IMAGE *imb, int type) { if ( (szcompat(imr,img) != NO_ERROR) || (szcompat(img,imb) != NO_ERROR) ){ (void)sprintf(buf,"imrgb2hsx(): images of different sizes or type\n"); errputstr(buf); } switch (GetImDataType(imr)){ case t_UCHAR: return(uc_imrgb2hsx(imr, img, imb, type)); break; default: (void)sprintf(buf,"imrgb2hsx(): invalid pixel type\n"); errputstr(buf); return(NULL); } } #include "g_def.h" IMAGE *generic_crgb2rgb(IMAGE *imh, IMAGE *iml, IMAGE *ims) { PIX_TYPE h, l, s; mia_size_t k, npix; IMAGE *imout; PIX_TYPE *pimh, *piml, *pims, *pout; imout = (IMAGE *)create_image(t_RGB, GetImNx(imh), GetImNy(imh), 1); if (imout == NULL){ (void)sprintf(buf,"generic_crgb2rgb(): not enough memory!\n"); errputstr(buf); return(imout); } pout=(PIX_TYPE *)GetImPtr(imout); pimh=(PIX_TYPE *)GetImPtr(imh); piml=(PIX_TYPE *)GetImPtr(iml); pims=(PIX_TYPE *)GetImPtr(ims); npix=GetImNx(imh)*GetImNy(imh); for (k=0; k. ***********************************************************************/ /** @file * Lower completion of an image \cite soille-gratin94 * @author Pierre Soille */ #include #include #include #include "fifo.h" #include "miallib.h" #include "pqueue.h" /** \addtogroup group_dem * @{ */ /* ** Function to lower complete an image using 4- or 8-connected geodesic distance ** see \cite{soille-gratin94}. */ /* Replaced 0x8000 by PIX_MSB on 23-05-2001 */ #include "us_def.h" ERROR_TYPE us_complete(IMAGE *im_i, IMAGE *im_rmin, int graph) { FIFO4 **fifo; FIFO4 *pf; PIX_TYPE *p, *pk, *p_i; PIX_TYPE h, hcrt, hmin, hmax; INT32 *pnb, i, k, count; UCHAR *p_w; G_TYPE *pg; int box[6]; long int shft[8]; pg=min_max(im_i); hmin=pg[0].us_val; hmax=pg[1].us_val; free((char *)pg); set_seq_shift(GetImNx(im_i), GetImNy(im_i),GetImNz(im_i), graph, shft); if ((pnb = (INT32 *)calloc(hmax + 1, sizeof(INT32 *))) == NULL){ (void) sprintf(buf, "complete(): not enough memory for pnb array (hmax=%d)\n", hmax); errputstr(buf); return ERROR; } /* Create an array of FIFO */ if ((fifo = (FIFO4 **)calloc(hmax + 1, sizeof(FIFO4 *))) == NULL){ (void) sprintf(buf, "complete(): not enough memory for the FAH\n"); errputstr(buf); free((char *)pnb); return ERROR; } for (i = hmin; i <= hmax; i++) fifo[i] = create_fifo4(10); /* GetImNx(im_i));*/ BOX_2D; uc_framebox(im_rmin, box, 0); /* initialize FAH */ p_i = (PIX_TYPE *)GetImPtr(im_i); p_w = (UCHAR *)GetImPtr(im_rmin); LOOPDN(i, GetImNPix(im_i)){ if (*p_w == 1){ fifo4_add(fifo[*p_i], (long int )p_i); pnb[*p_i] += 1; *p_i = PIX_MSB; } p_i++; p_w++; } /* boucle principale */ us_framebox(im_i, box, PIX_MSB); h = hmin; for (hcrt = hmin; hcrt <= hmax; hcrt++){ pf = fifo[hcrt]; if (pf != NULL){ while (fifo4_empty(pf) == FALSE){ count = pnb[hcrt]; pnb[hcrt] = 0; for (i = 0; i < count; i++){ p = (PIX_TYPE *)fifo4_remove(pf); *p |= h; for (k = 0; k < graph; ++k){ pk = p + shft[k]; if ((*pk & PIX_MSB) == PIX_MSB) continue; fifo4_add(fifo[*pk], (long int)pk); pnb[*pk] +=1; *pk = PIX_MSB; } } h++; } free_fifo4(pf); } } free((char *)fifo); p = (PIX_TYPE *)GetImPtr(im_i); LOOPDN(i, GetImNPix(im_i)){ *p ^= PIX_MSB; p++; } return NO_ERROR; } #include "us_undef.h" #include "u32_def.h" ERROR_TYPE u32_complete(IMAGE *im_i, IMAGE *im_rmin, int graph) { FIFO4 **fifo; FIFO4 *pf; PIX_TYPE *p, *pk, *p_i; PIX_TYPE h, hcrt, hmin, hmax; INT32 *pnb, i, k, count; UCHAR *p_w; G_TYPE *pg; int box[6]; long int shft[8]; pg=min_max(im_i); hmin=pg[0].u32_val; hmax=pg[1].u32_val; free((char *)pg); set_seq_shift(GetImNx(im_i), GetImNy(im_i), GetImNz(im_i), graph, shft); if ((pnb = (INT32 *)calloc(hmax + 1, sizeof(INT32 *))) == NULL){ (void) sprintf(buf, "complete(): not enough memory for pnb array (hmax=%u)\n", hmax); errputstr(buf); return ERROR; } /* Create an array of FIFO */ if ((fifo = (FIFO4 **)calloc(hmax + 1, sizeof(FIFO4 *))) == NULL){ (void) sprintf(buf, "complete(): not enough memory for the FAH\n"); errputstr(buf); free((char *)pnb); return ERROR; } for (i = hmin; i <= hmax; i++) fifo[i] = create_fifo4(10); /* GetImNx(im_i));*/ BOX_2D; uc_framebox(im_rmin, box, 0); /* initialize FAH */ p_i = (PIX_TYPE *)GetImPtr(im_i); p_w = (UCHAR *)GetImPtr(im_rmin); LOOPDN(i, GetImNPix(im_i)){ if (*p_w == 1){ fifo4_add(fifo[*p_i], (long int )p_i); pnb[*p_i] += 1; *p_i = PIX_MSB; } // else if (*p_i == 0) // *p_i = PIX_MSB; p_i++; p_w++; } /* boucle principale */ u32_framebox(im_i, box, PIX_MSB); h = hmin; for (hcrt = hmin; hcrt <= hmax; hcrt++){ pf = fifo[hcrt]; if (pf != NULL){ while (fifo4_empty(pf) == FALSE){ count = pnb[hcrt]; pnb[hcrt] = 0; for (i = 0; i < count; i++){ p = (PIX_TYPE *)fifo4_remove(pf); *p |= h; for (k = 0; k < graph; ++k){ pk = p + shft[k]; if ((*pk & PIX_MSB) == PIX_MSB) continue; fifo4_add(fifo[*pk], (long int)pk); pnb[*pk] +=1; *pk = PIX_MSB; } } h++; } free_fifo4(pf); } } printf("h=%d\n", (int)h); free((char *)fifo); p = (PIX_TYPE *)GetImPtr(im_i); LOOPDN(i, GetImNPix(im_i)){ *p ^= PIX_MSB; p++; } return NO_ERROR; } #include "u32_undef.h" ERROR_TYPE complete(IMAGE *im_i, IMAGE *im_rmin, int graph) { if (GetImDataType(im_rmin)!=t_UCHAR){ (void) printf("complete(IMAGE *im_i, IMAGE *im_rmin, int graph): im_rmin must be of type UCHAR\n"); return ERROR; } switch (GetImDataType(im_i)){ case t_USHORT: return(us_complete(im_i, im_rmin, graph)); break; case t_INT32: return(u32_complete(im_i, im_rmin, graph)); break; default: (void) printf("complete(IMAGE *im_i, IMAGE *im_rmin, int graph): invalid pixel type for im_i\n"); return ERROR; } return ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/compose.c000066400000000000000000000462401467232417700174000ustar00rootroot00000000000000 /*********************************************************************** Author(s): Pierre Soille Copyright (C) 2004-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "fifo.h" #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif /** @defgroup group_compose Morphological Compositing functions * Functions related to Morphological Image Compositing \cite soille2006pami * https://doi.org/10.1109/TPAMI.2006.99 * @{ */ /* COMPOSITING: first 28-9-2004 */ #include "pqueue.h" #include "uc_def.h" /* for mask, marker and g */ #define GIM_TYPE UCHAR #define MARKERIM_TYPE UCHAR #define PIXLBL_TYPE USHORT ERROR_TYPE us_compose(IMAGE *mark, IMAGE *mask, IMAGE *g, IMAGE *lbl, int graph) { /* mark: indicates index of image each pixel (0 value => no marker), overwritten by output. Note: border of mark is set to 0!!! mask: segmentation function for watershed propagation g: image with number of overlap for each pixel (0=>outside of ROI) border of g is set to 0!!! New version where g is actually created by gorder. lbl: lbl(x)=\sum_2^i | f_i(x) is in ROI of f_i graph: integer for connectivity */ struct pqueue **pq; /* array of priority queues */ PQDATUM apqd[1]; struct node *pqd; G_TYPE *pgval; GIM_TYPE card, maxii, *pg; PIX_TYPE *pmask; MARKERIM_TYPE *pmark; PIXLBL_TYPE *plbl; int i,j,k; long int npix, ofs, ofsk; long int shift[27]; int box[6]; /* test image types and set border */ if ( (GetImDataType(g)!=t_UCHAR) || (GetImDataType(mark)!=t_UCHAR) ){ (void)sprintf(buf,"ERROR in compose(mark,mask,g,graph): \ invalid type for g or mark\n"); errputstr(buf); return ERROR; } if (GetImNy(g) == 1) {BOX_1D;} else if (GetImNz(g) == 1) {BOX_2D;} else {BOX_3D;} uc_framebox(g,box,0); uc_framebox(mark,box,0); /* get max value of g */ pgval = min_max(g); if (pgval == NULL) return(ERROR); maxii = pgval[1].uc_val; free((char *)pgval); /* allocate maxii+1 priority queues */ pq=(struct pqueue **)calloc(maxii+1,sizeof(struct pqueue *)); for (i=2; i<=maxii; i++){ pq[i] = (struct pqueue *)pqinit(NULL, 1024); /* priority queue */ if (pq[i] == NULL){ for (j=2; j1){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = pmask[ofs]; pqd->val = pmark[i]; pqd->offset= ofs; pqmininsert(pq[card], pqd); pg[ofs]=0; /* reset number of overlap */ } } } } } } printf("message: composition heap initialised\n"); /* here we go */ for (i=2;i<=maxii;i++){ while ( pqpeek(pq[i], apqd) != NULL ){ pqminremove(pq[i], apqd); ofs = apqd[0]->offset; pmark[ofs] = apqd[0]->val; for(k=0;k1){ pqd = (PQDATUM )malloc(sizeof(struct node)); /* if card > i: do not compute max!!! */ if (card>i) pqd->prio = pmask[ofsk]; else pqd->prio = max(pmask[ofsk],apqd[0]->prio); pqd->val = pmark[ofs]; pqd->offset= ofsk; pqmininsert(pq[card], pqd); pg[ofsk]=0; /* reset number of overlap */ } } } free((char*) *apqd); } } /* set pseudo-indice values to actual indices */ for (j=2; j<=maxii; j++) free_pq(pq[j]); free(pq); return NO_ERROR; } #undef GIM_TYPE #undef MARKERIM_TYPE #undef PIXLBL_TYPE #include "uc_undef.h" #include "uc_def.h" /* for mask, marker and g */ #define GIM_TYPE UCHAR #define MARKERIM_TYPE UCHAR #define PIXLBL_TYPE UINT32 ERROR_TYPE u32_compose(IMAGE *mark, IMAGE *mask, IMAGE *g, IMAGE *lbl, int graph) { /* mark: indicates index of image each pixel (0 value => no marker), overwritten by output. Note: border of mark is set to 0!!! mask: segmentation function for watershed propagation g: image with number of overlap for each pixel (0=>outside of ROI) border of g is set to 0!!! New version where g is actually created by gorder. lbl: lbl(x)=\sum_2^i | f_i(x) is in ROI of f_i graph: integer for connectivity */ struct pqueue **pq; /* array of priority queues */ PQDATUM apqd[1]; struct node *pqd; G_TYPE *pgval; GIM_TYPE card, maxii, *pg; PIX_TYPE *pmask; MARKERIM_TYPE *pmark; PIXLBL_TYPE *plbl; int i,j,k; long int npix, ofs, ofsk; long int shift[27]; int box[6]; /* test image types and set border */ if ( (GetImDataType(g)!=t_UCHAR) || (GetImDataType(mark)!=t_UCHAR) ){ (void)sprintf(buf,"ERROR in compose(mark,mask,g,graph): \ invalid type for g or mark\n"); errputstr(buf); return ERROR; } if (GetImNy(g) == 1) {BOX_1D;} else if (GetImNz(g) == 1) {BOX_2D;} else {BOX_3D;} uc_framebox(g,box,0); uc_framebox(mark,box,0); /* get max value of g */ pgval = min_max(g); if (pgval == NULL) return(ERROR); maxii = pgval[1].uc_val; free((char *)pgval); /* allocate maxii+1 priority queues */ pq=(struct pqueue **)calloc(maxii+1,sizeof(struct pqueue *)); for (i=2; i<=maxii; i++){ pq[i] = (struct pqueue *)pqinit(NULL, 1024); /* priority queue */ if (pq[i] == NULL){ for (j=2; j1){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = pmask[ofs]; pqd->val = pmark[i]; pqd->offset= ofs; pqmininsert(pq[card], pqd); pg[ofs]=0; /* reset number of overlap */ } } } } } } printf("message: composition heap initialised\n"); /* here we go */ for (i=2;i<=maxii;i++){ while ( pqpeek(pq[i], apqd) != NULL ){ pqminremove(pq[i], apqd); ofs = apqd[0]->offset; pmark[ofs] = apqd[0]->val; for(k=0;k1){ pqd = (PQDATUM )malloc(sizeof(struct node)); /* if card > i: do not compute max!!! */ if (card>i) pqd->prio = pmask[ofsk]; else pqd->prio = max(pmask[ofsk],apqd[0]->prio); pqd->val = pmark[ofs]; pqd->offset= ofsk; pqmininsert(pq[card], pqd); pg[ofsk]=0; /* reset number of overlap */ } } } free((char*) *apqd); } } /* set pseudo-indice values to actual indices */ for (j=2; j<=maxii; j++) free_pq(pq[j]); free(pq); return NO_ERROR; } #undef GIM_TYPE #undef MARKERIM_TYPE #undef PIXLBL_TYPE #include "uc_undef.h" /* ERROR_TYPE uc_compose(IMAGE *mark, IMAGE *mask, IMAGE *g, IMAGE *lbl, int graph) */ /* { */ /* switch(GetImDataType(mark)){ */ /* case t_UCHAR: */ /* return(uc_uc_compose(mark,mask,g,lbl,graph)); */ /* break; */ /* default: */ /* (void)sprintf(buf,"compose(): invalid pixel type for mark image\n"); errputstr(buf); */ /* return(ERROR); */ /* } */ /* return(NO_ERROR); */ /* } */ ERROR_TYPE compose(IMAGE *mark, IMAGE *mask, IMAGE *g, IMAGE *lbl, int graph) { if ( (szgeocompat(mark, mask) != NO_ERROR) || \ (szgeocompat(mask, g) != NO_ERROR) || \ (szgeocompat(mask, lbl) != NO_ERROR) ){ (void)sprintf(buf,"ERROR in compose(mark,mask,g,graph): \ images of different size\n"); errputstr(buf); return ERROR; } if ( (GetImDataType(mark)!=t_UCHAR) || (GetImDataType(mask)!=t_UCHAR) \ || (GetImDataType(g)!=t_UCHAR) ){ (void)sprintf(buf,"ERROR in compose(mark,mask,g,lbl,graph): \ image mark, mask, and g must be of type UCHAR\n"); errputstr(buf); return ERROR; } /* if ( (GetImDataType(lbl)!=t_USHORT) || (GetImDataType(lbl)!=t_UINT32) ){ */ /* (void)sprintf(buf,"ERROR in compose(mark,mask,g,lbl,graph): \ */ /* image lbl must be opf type USHORT or UINT32\n"); */ /* errputstr(buf); */ /* return ERROR; */ /* } */ switch(GetImDataType(lbl)){ case t_USHORT: return(us_compose(mark,mask,g,lbl,graph)); break; case t_UINT32: return(u32_compose(mark,mask,g,lbl,graph)); break; default: (void)sprintf(buf,"compose(): invalid pixel type for lbl image\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" #define HST1D_TYPE_MAX INT32_MAX ERROR_TYPE uc_resolveLabels(IMAGE *imlbl, IMAGE *imlut, IMAGE *imlutback, int graph) { UINT32 *ngbval, maxfreq; int i, j, k, kmax=GetImNx(imlutback); long int shft[27]; long int npix=GetImNPix(imlbl); int box[6]; PIX_TYPE *plbl=(PIX_TYPE *)GetImPtr(imlbl); PIX_TYPE *p1, *p2, maxlbl, lblmaj; HST1D_TYPE *plut=(HST1D_TYPE *)GetImPtr(imlut); HST1D_TYPE *plutback=(HST1D_TYPE *)GetImPtr(imlutback), crtlbl; FIFO4 *q, *qall; G_TYPE *pg; /* take graph into account */ if (set_seq_shift(GetImNx(imlbl), GetImNy(imlbl), GetImNz(imlbl), graph, shft) == ERROR) return ERROR; /* get min & max values */ pg = min_max(imlbl); if (pg == NULL) return(ERROR); maxlbl = pg[1].uc_val; free((char *)pg); ngbval=(UINT32 *)calloc(maxlbl+1,sizeof(UINT32)); if (ngbval==NULL) return ERROR; q = create_fifo4(1024); if (q == NULL){ free((char*)ngbval); return ERROR; } qall = create_fifo4(1024); if (qall == NULL){ free((char*)ngbval); free_fifo4(q); return ERROR; } if (GetImNy(imlbl) == 1) {BOX_1D;} else if (GetImNz(imlbl) == 1) {BOX_2D;} else {BOX_3D;} /* last bit of imlbl used for flagging and borders ! That is, maximum label value should be PIX_MAX xor PIX_MSB */ uc_framebox(imlbl, box, PIX_MSB); /* scan image */ for(i=0;imaxfreq){ lblmaj=j; maxfreq=ngbval[j]; } } if(lblmaj==0){ // printf("message: lblmaj=0 in resolvelabels: choose first pure label\n"); crtlbl=plutback[crtlbl]; for (j=1;jmaxfreq){ lblmaj=j; maxfreq=ngbval[j]; } } if(lblmaj==0){ flag=0; toto=crtlbl; // printf("message: lblmaj=0 in resolvelabels: choose first pure label\n"); crtlbl=plutback[crtlbl]; if (crtlbl==0) printf("GLOUP: plutback[%d]=%d\n", (int)crtlbl, (int)(plutback[crtlbl])); for (j=1;j. ***********************************************************************/ #include #include #include #ifdef OPENMP #include #endif #include "miallib.h" #include "op.h" /** @defgroup group_convolve Image convolution, correlation, and other kernel operations * Functions dealing with image convolution, correlationm, and other kernel operations. * @{ */ #define PIX_TYPE unsigned char void uc_convolve(PIX_TYPE *im1, MIALFLOAT *im2, int nx, int ny, int nz, \ int *box, long int *shft, MIALFLOAT *weight, int n) { PIX_TYPE *p1; MIALFLOAT *p2; long int i, k, y, z, nxi, ofs; long int lsty, lstz; nxi=nx-box[0]-box[1]; lsty = ny - box[3]; lstz = nz - box[5]; for (z = box[4]; z < lstz; z++){ for (y = box[2]; y < lsty; y++){ ofs=nx*ny*z + nx*y + box[0]; p1=im1+ofs; p2=im2+ofs; #ifdef OPENMP #pragma omp parallel for private(i,k) #endif for (i=0;i0){ *px=(PIX_TYPE)rad2deg(PI/2); } else{ *px=(PIX_TYPE)rad2deg(3*PI/2); } } else if (dy<0){ *px=(PIX_TYPE)rad2deg(2*PI+atan((double)dy/dx)); } else *px=(PIX_TYPE)rad2deg(atan((double)dy/dx)); } return NO_ERROR; } #include "i32_undef.h" #include "f_def.h" ERROR_TYPE f_azimuth(IMAGE *ix, IMAGE *iy) { long int i, dx, dy, npix; PIX_TYPE *px, *py; if (szcompat(ix, iy)==ERROR) return ERROR; npix=GetImNx(ix)*GetImNy(iy); px=(PIX_TYPE *)GetImPtr(ix); py=(PIX_TYPE *)GetImPtr(iy); for (i=0; i0){ *px=(PIX_TYPE)rad2deg(PI/2); } else{ *px=(PIX_TYPE)rad2deg(3*PI/2); } } else if (dy<0){ *px=(PIX_TYPE)rad2deg(2*PI+atan((double)dy/dx)); } else *px=(PIX_TYPE)rad2deg(atan((double)dy/dx)); } return NO_ERROR; } #include "f_undef.h" ERROR_TYPE azimuth(IMAGE *ix, IMAGE *iy) { if (szcompat(ix, iy)==ERROR) return ERROR; switch (GetImDataType(ix)){ case t_UINT32: return(i32_azimuth(ix, iy)); break; case t_FLOAT: return(f_azimuth(ix, iy)); break; default: (void)sprintf(buf,"aximuth(ix, iy): invalid pixel type\n"); errputstr(buf); } return ERROR; } #include "uc_def.h" #define rad2deguchar(x) ((x)*((double)PIX_MAX/(2*PI))) /* radians to uchar values */ ERROR_TYPE uc_mapori(IMAGE *i0, int ox, int oy) { long int x, y, nx, ny; PIX_TYPE *pi; nx=GetImNx(i0); ny=GetImNy(i0); pi=(PIX_TYPE *)GetImPtr(i0); for (y=0; yox){ *pi=(PIX_TYPE)rad2deguchar(PI+atan((double)(oy-y)/(ox-x))); } else if (ox==x){ if (yoy){ *pi=(PIX_TYPE)rad2deguchar(2*PI+atan((double)(oy-y)/(ox-x))); } else{ *pi=(PIX_TYPE)rad2deguchar(atan((double)(oy-y)/(ox-x))); } pi++; } } return NO_ERROR; } #include "uc_undef.h" #include "us_def.h" #define rad2degushort(x) ((x)*((double)PIX_MAX/(2*PI))) /* radians to uchar values */ ERROR_TYPE us_mapori(IMAGE *i0, int ox, int oy) { long int x, y, nx, ny; PIX_TYPE *pi; nx=GetImNx(i0); ny=GetImNy(i0); pi=(PIX_TYPE *)GetImPtr(i0); for (y=0; yox){ *pi=(PIX_TYPE)rad2degushort(PI+atan((double)(oy-y)/(ox-x))); } else if (ox==x){ if (yoy){ *pi=(PIX_TYPE)rad2degushort(2*PI+atan((double)(oy-y)/(ox-x))); } else{ *pi=(PIX_TYPE)rad2degushort(atan((double)(oy-y)/(ox-x))); } pi++; } } return NO_ERROR; } #include "us_undef.h" /** * @synopsis orientation map of a raster with respect to an origin * * @param i0: an IMAGE * @param ox: x-coordinate of an origin in pixel space * @param oy: y-coordinate of an origin in pixel space * @desc sets each pixel of the input image i0 to its orientation with respect to an origin with pixel coordinates (ox,oy). The values are given in degrees rescaled according to the data type of the input image. */ ERROR_TYPE mapori(IMAGE *i0, int ox, int oy) { switch (GetImDataType(i0)){ case t_UCHAR: return(uc_mapori(i0, ox, oy)); break; case t_USHORT: return(us_mapori(i0, ox, oy)); break; default: (void)sprintf(buf,"mapori(): invalid pixel type\n"); errputstr(buf); } return ERROR; } #include "uc_def.h" IMAGE *uc_rsum2d(IMAGE *im) { PIX_TYPE *p; int x, y, nx, ny; unsigned long int ofs; IMAGE *imout; INT32 *s; /* create output image */ imout = (IMAGE *)create_image(t_INT32, GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"uc_rsum2d(): not enough memory!\n"); errputstr(buf); return(imout); } nx=GetImNx(im); ny=GetImNy(im); p=(PIX_TYPE *)GetImPtr(im); s=(INT32 *)GetImPtr(imout); *s=*p; for(x=1;x k-1 || oy < 0 || oy > k-1){ (void)sprintf(buf,"Invalid origin, must be in SE\n"); stdputstr(buf); return NULL; } /* create output image */ imo = create_image((int)t_INT32, ncol, nlin, (int)1); if (imo==NULL){ (void)sprintf(buf,"Not enough memory in uc_squarevol()\n"); stdputstr(buf); return NULL; } po = (INT32 *)GetImPtr(imo); /* allocate and initialise shifts arrays */ nshft=k*k; shft=(int *)calloc(nshft, sizeof(int)); /* all pixels of SE */ for (y=0, i=0; y. ***********************************************************************/ /* macro definitions for unsigned double data types */ #define FLOATING 1 #define SIGNED 1 #define OVFL_TEST 0 #define t_PIX_TYPE t_DOUBLE #define PIX_TYPE DOUBLE #define PIX_MIN DOUBLE_MIN #define PIX_MAX DOUBLE_MAX jeolib-miallib-1.1.6/core/c/d_undef.h000066400000000000000000000020101467232417700173270ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for unsigned double data types */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX jeolib-miallib-1.1.6/core/c/dbscan.c000066400000000000000000000115711467232417700171640ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2012-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "fifo.h" #ifdef OPENMP #include #endif #include "f_def.h" #define NCMAX 255 /* maximum number of channels */ #define SIM_PIX_TYPE MIALFLOAT #define t_SIM_PIX_TYPE t_FLOAT IMAGE *f_dissim(IMAGE **imap, int nc, IMAGE *mask, int type) { /* compute dissimilarity matrix using type distance and only for points in mask (other have a similarity set to -1. First: 20120130 */ long int i, j, npix; int c; IMAGE *sim; PIX_TYPE *p[NCMAX]; SIM_PIX_TYPE *psim; UCHAR *pmask; /* Here we go */ for (c=0;c=minpts){ lbl++; plbl[i]=lbl; printf("i=%ld npts=%d lbl=%d\n", i, npts, lbl); for(x=0;x. ***********************************************************************/ #include #include #include #include "miallib.h" extern ERROR_TYPE us_plotline(); ERROR_TYPE agglo_cluster(int *x, int *y, int *pn, double maxdst) { /* ** authors: P. Soille ** int *x: array of x coordinates of data points ** int *y: array of y coordinates of data points ** int *pn: contains the number of data points ** double maxdst: maximum distance for clustering 2 points ** comment: 1st July 1999 (1st version: Result depends on the order for scanning the pixels). */ IMAGE *imdst; int i,j, cnt=0, n=*pn, crtx,crty; DOUBLE *pdst, crtdst; /* create image of distances */ imdst = (IMAGE *)create_image(t_DOUBLE, n, n, (int)1); if (imdst == NULL){ (void)sprintf(buf,"dst_cluster(): not enough memory!\n"); errputstr(buf); return(ERROR); } pdst=(double *)GetImPtr(imdst); for (j=0; j. ***********************************************************************/ #include #include #include #include #include "miallib.h" /** \addtogroup group_seg * @{ */ #include "u32_def.h" #define PIX_TYPE_M1 USHORT #define t_PIX_TYPE_M1 t_USHORT IMAGE **u32_imgc(IMAGE *imlbl) { IMAGE **gc; IMAGE *im00, *im10, *im01; PIX_TYPE_M1 *m00, *m10, *m01; PIX_TYPE *plbl; unsigned long nx, ny, maxlbl; long int x, y; double maxval; nx=GetImNx(imlbl); ny=GetImNy(imlbl); /* initialisation */ getmax(imlbl, &maxval); maxlbl=(unsigned long)maxval; fprintf(stderr, "mxlbl=%d\n", (int) maxlbl); gc=(IMAGE **)malloc(2 * sizeof(IMAGE *)); im00 = (IMAGE *)create_image(t_USHORT, maxlbl+1, 1, 1); if (im00 == NULL){ (void)sprintf(buf,": not enough memory!\n"); errputstr(buf); return NULL; } im10 = (IMAGE *)create_image(t_PIX_TYPE_M1, maxlbl+1, 1, 1); if (im10 == NULL){ (void)sprintf(buf,": not enough memory!\n"); errputstr(buf); return NULL; } im01 = (IMAGE *)create_image(t_PIX_TYPE_M1, maxlbl+1, 1, 1); if (im10 == NULL){ (void)sprintf(buf,": not enough memory!\n"); errputstr(buf); return NULL; } fprintf(stderr, "CG0\n"); plbl=(PIX_TYPE *)GetImPtr(imlbl); m00=(USHORT *)GetImPtr(im00); m10=(PIX_TYPE_M1 *)GetImPtr(im10); m01=(PIX_TYPE_M1 *)GetImPtr(im01); for (y=0; y=0; x--){ if(m00[x]){ m10[x]/= m00[x]; m01[x]/= m00[x]; } } free_image(im00); gc[0]=im10; gc[1]=im01; return gc; } #undef PIX_TYPE_M1 #undef t_PIX_TYPE_M1 #include "u32_undef.h" IMAGE **imgc(IMAGE *imlbl) { switch (GetImDataType(imlbl)){ case t_UINT32: case t_INT32: return u32_imgc(imlbl); break; default: return(NULL); } return(NULL); } /** * @synopsis outputs dendrogram of input partition hierarchy in ascii file * * @param imap: array of labelled images (fine to coarse partition hierarchy) * @param nc: number of levels of the hierarchy * @param fn: string for file name to write dendrogram in ascii format * * @return 1 on failure, 0 otherwise * * @creationdate 20130911 */ ERROR_TYPE dendro(IMAGE **imap, int nc, char *fn) { /* imap: array of labelled images (fine to coarse partition hierarchy) nc: number of levels of the hierarchy fn: name of output ascii file */ FILE *fp; IMAGE *imcrt, *imnxt; UINT32 *pcrt, *pnxt; char *flaga; IMAGE **cgcrt=NULL, **cgnxt=NULL; USHORT *pxc, *pxn, *pyc, *pyn; int h; unsigned long int npix, maxlbl; long int i; double maxval; npix=GetImNPix(imap[0]); /* initialisation */ iminfo(imap[0]); iminfo(imap[1]); getmax(imap[1], &maxval); maxlbl=(unsigned long)maxval; fprintf(stderr, "mxlbl=%d\n", (int) maxlbl); getmax(imap[0], &maxval); maxlbl=(unsigned long)maxval; fprintf(stderr, "mxlbl=%d\n", (int) maxlbl); flaga=(char *)malloc((maxlbl+1) * sizeof(char)); if (flaga==NULL){ (void)sprintf(buf,"dendro(): not enough memory for flag array\n"); errputstr(buf); return(ERROR); } if ((fp = fopen(fn, "w")) == NULL){ (void)sprintf(buf,"ERROR in dendro() unable to write in %s", fn); errputstr(buf); free(flaga); return(ERROR); } fprintf(stderr, "nc=%d\n", (int) nc); cgnxt=imgc(imap[nc-1]); if (cgnxt==NULL){ free(flaga); return(ERROR); } fprintf(stderr, "COUCOU0\n"); /* here we go */ for (h=nc-1; h>0; h--){ fprintf(stderr, "h=%d\n", (int) h); imcrt=imap[h]; pcrt= (UINT32 *) GetImPtr(imcrt); imnxt=imap[h-1]; pnxt= (UINT32 *) GetImPtr(imnxt); cgcrt=cgnxt; pxc=(USHORT *)GetImPtr(cgcrt[0]); pyc=(USHORT *)GetImPtr(cgcrt[1]); cgnxt=imgc(imnxt); if (cgnxt==NULL){ free(flaga); return(ERROR); } pxn=(USHORT *)GetImPtr(cgnxt[0]); pyn=(USHORT *)GetImPtr(cgnxt[1]); memset(flaga, 0x1, maxlbl+1); fprintf(stderr, "COUCOU4\n"); for (i=npix-1; i>=0; i--){ if (flaga[pnxt[i]]){ fprintf(fp, "%d %d %d\n %d %d %d\n\n\n", pxc[pcrt[i]], pyc[pcrt[i]], h, \ pxn[pnxt[i]], pyn[pnxt[i]], h-1); flaga[pnxt[i]]=0; } } free_image(cgcrt[0]); free_image(cgcrt[1]); free(cgcrt); } free(flaga); free_image(cgnxt[0]); free_image(cgnxt[1]); free(cgnxt); fclose(fp); return NO_ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/determineSize.c000066400000000000000000000302111467232417700205310ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Iterative regiona growing \cite brunner-soille2005 \cite brunner-soille2007 * @author Dominik Brunner and Pierre Soille */ /*************************************************************************** determineSize.c - description ------------------- begin : Tue APR 13 2004 ***************************************************************************/ #include #include #include "mslabel.h" #include "miallib.h" #include "base.h" #include "fifo.h" #include "regionMean.h" #include "math.h" #include "determineSize.h" struct status { unsigned int is_labeled : 1; unsigned int is_contrast_labeled : 1; }; /* * thresholdRegion_Size: Algorithm to determine the size of the regions. If the thresholdvalue * is 0, then the values of the pixels in the image are replaced by the * corresponding size values of the region the pixel belongs to. * Otherwise the region gets an increasing region number if the size is * bigger then the threshold. * * Parameters: * * inputIm input image which shall be thresholded. The result is stored in this image * * threshold region size must be bigger than this threshold value. Otherwise the values * of the pixels of this region are set to 0; * * * Return values: * * 0 if there is an Error * * >1 number of regions which are left after thresholding the image */ long int thresholdRegion_Size(IMAGE *inputIm, unsigned long int threshold) { long int shft[27], i, label=SEED; int nx, ny; LBL_TYPE count, k, offset, neighbourOffset, crtOffset, *pInputIm; IMAGE *im; // Image for storing whether pixel already // processed (LABELED) or not (NOTLABELED) UCHAR *pIm; FIFO4 *nq, *rq; // neighbourQueue, regionQueue int box[6]; // initilize box for frame which shall be added in order to solve // problem with neighbours box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; // check whether image has datatype unsigned long int if (GetImDataType(inputIm) != t_LBL_TYPE){ sprintf(buf,"error in thresholdRegion_Size(): wrong data type for inputIm\n"); return ERROR; } if (u32_addframebox(inputIm, box, BORDER) == ERROR){ return ERROR; } im = (IMAGE *) create_image(t_UCHAR, GetImNx(inputIm), GetImNy(inputIm), 1); if (uc_framebox(im, box, BORDER) == ERROR){ return ERROR; } nx= GetImNx(inputIm); ny= GetImNy(inputIm); if (set_seq_shift(GetImNx(inputIm), GetImNy(inputIm), GetImNz(inputIm), 8, shft) == ERROR){ return ERROR; } nq = create_fifo4(nx * ny / 100L); rq = create_fifo4(nx * ny / 100L); pInputIm = (LBL_TYPE *) GetImPtr(inputIm); pIm = (UCHAR *) GetImPtr(im); for (i = 0; i < nx * ny; i++){ count = 0; if ((*(pIm + i)) == NOTLABELED){ offset = i; count++; // put this pixel to region queue fifo4_add(rq, (long int) offset); (*(pIm + offset)) = LABELED; // check the neighbours for (k = 0; k < 8; k++){ neighbourOffset = offset + shft[k]; if ((*(pIm + neighbourOffset)) == NOTLABELED){ //printf("offset: %i",(*(pInputIm + offset) )); //printf("neighbourOffset: %i", (*(pInputIm + neighbourOffset))); if ((*(pInputIm + neighbourOffset)) == (*(pInputIm + offset))){ fifo4_add(nq, (long int) (neighbourOffset)); (*(pIm + neighbourOffset)) = LABELED; fifo4_add(rq, (long int) (neighbourOffset)); count++; } } } while (fifo4_empty(nq) == 0){ crtOffset = (long int) fifo4_remove(nq); for (k = 0; k < 8; k++){ neighbourOffset = crtOffset + shft[k]; if ((*(pIm + neighbourOffset)) == NOTLABELED){ if ((*(pInputIm + neighbourOffset)) == (*(pInputIm + offset))) { fifo4_add(nq, (long int) (neighbourOffset)); (*(pIm + neighbourOffset)) = LABELED; fifo4_add(rq, (long int) (neighbourOffset)); count++; } } } } if((threshold == 0)){ while (fifo4_empty(rq) == 0){ offset = (long int) fifo4_remove(rq); (*(pInputIm + offset)) = count; } label++; } else if (count >= threshold){ while (fifo4_empty(rq) == 0){ offset = (long int) fifo4_remove(rq); (*(pInputIm + offset)) = label; } label++; } else{ while(fifo4_empty(rq) == 0){ offset = (long int)fifo4_remove(rq); (*(pInputIm + offset)) = 0; } } } } free_image(im); free_fifo4(nq); free_fifo4(rq); subframebox(inputIm, box); if(threshold >=0){ return (label-1); }else{ return NO_ERROR; } } /* * thresholdRegion_Contrast: Algorithm to determine the contrast values of the regions. * If the thresholdvalue * is 0, then the values of the pixels in the image are replaced by the * corresponding contrast values of the region the pixel belongs to. * Otherwise the region gets an increasing region number if the size is * bigger then the threshold. * * Parameters: * * imap image array with the different channels of the image * * nc number of channels * * inputIm input image which shall be thresholded. The result is stored in this image * * threshold contrast value of the region must be bigger than this threshold value. * Otherwise the values * of the pixels of this region are set to 0; * * * Return values: * * 0 if there is an Error * * >1 number of regions which are left after thresholding the image */ long int thresholdRegion_Contrast(IMAGE **imap, int nc, IMAGE *inputIm, unsigned long int threshold) { long int shft[27], i, label=SEED; int nx, ny; LBL_TYPE count, countContrastPixel, k, offset, neighbourOffset, crtOffset, *pInputIm; FIFO4 *nq, *rq, *cq; // neighbourQueue, regionQueue, contrastQueue struct regionMean rm; //stores the region mean colour informatiion for the current region double contrast, distance; int box[6]; struct status *crtStatus; // initilize box for frame which shall be added in order to solve // problem with neighbours box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; // check whether image has datatype unsigned long int if (GetImDataType(inputIm) != t_LBL_TYPE){ sprintf(buf,"error in thresholdRegion_Contrast(): wrong data type for inputIm\n"); return ERROR; } for (i = 0; i < nc; i++){ if (GetImDataType(imap[i])==t_UCHAR){ if (generic_addframebox(imap[i], box, (UCHAR)BORDER) == ERROR){ return ERROR; } } else if (GetImDataType(imap[i])==t_USHORT){ if (us_addframebox(imap[i], box, (USHORT)BORDER) == ERROR){ return ERROR; } } else{ return ERROR; } } if (u32_addframebox(inputIm, box, BORDER) == ERROR){ return ERROR; } //initialize regionMean if(rmInit(&rm, nc)==NULL){ return ERROR; } nx= GetImNx(inputIm); ny= GetImNy(inputIm); crtStatus = (struct status *) calloc(nx*ny, sizeof(struct status)); if (crtStatus==NULL){ freeRegionMean(&rm); return ERROR; } for(i=0; i<(nx*ny);i++){ //initialize values considering a frame outside if((i=(nx*ny-nx))|| (i%nx == nx-1) || (i%nx == 0)){ crtStatus[i].is_contrast_labeled=LABELED; crtStatus[i].is_labeled=LABELED; }else{ crtStatus[i].is_contrast_labeled=NOTLABELED; crtStatus[i].is_labeled=NOTLABELED; } } if (set_seq_shift(GetImNx(inputIm), GetImNy(inputIm), GetImNz(inputIm), 8, shft) == ERROR){ freeRegionMean(&rm); free(crtStatus); return ERROR; } nq = create_fifo4(nx * ny / 100L); rq = create_fifo4(nx * ny / 100L); cq = create_fifo4(nx * ny / 100L); pInputIm = (LBL_TYPE *) GetImPtr(inputIm); for (i = 0; i < nx * ny; i++){ count = 0; countContrastPixel = 0; clearRegionMean(&rm); contrast=0; if (crtStatus[i].is_labeled == NOTLABELED){ offset = i; count++; // put this pixel to region queue fifo4_add(rq, (long int) offset); rmAddValue(&rm, imap, (long int) offset); crtStatus[offset].is_labeled = LABELED; // check the neighbours for (k = 0; k < 8; k++){ neighbourOffset = offset + shft[k]; if ((crtStatus[neighbourOffset].is_labeled == NOTLABELED) && \ ((*(pInputIm + neighbourOffset)) ==(*(pInputIm + offset)))){ fifo4_add(nq, (long int) (neighbourOffset)); crtStatus[neighbourOffset].is_labeled = LABELED; fifo4_add(rq, (long int) (neighbourOffset)); rmAddValue(&rm, imap, (long int) neighbourOffset); count++; }else{ //check whether the pixel is already in the queue which stores the pixel to determine the contrast if((crtStatus[neighbourOffset].is_contrast_labeled == NOTLABELED) && \ ((*(pInputIm + neighbourOffset)) != (*(pInputIm + offset)))){ fifo4_add(cq, neighbourOffset); crtStatus[neighbourOffset].is_contrast_labeled = LABELED; countContrastPixel++; } } } while (fifo4_empty(nq) == 0){ crtOffset = (long int) fifo4_remove(nq); for (k = 0; k < 8; k++){ neighbourOffset = crtOffset + shft[k]; if ((crtStatus[neighbourOffset].is_labeled == NOTLABELED) && ((*(pInputIm + neighbourOffset)) == (*(pInputIm +crtOffset)))){ fifo4_add(nq, (long int) (neighbourOffset)); crtStatus[neighbourOffset].is_labeled = LABELED; fifo4_add(rq, (long int) (neighbourOffset)); rmAddValue(&rm, imap, (long int) neighbourOffset); count++; } else{ //check whether the pixel is already in the queue which stores the pixel to determine the contrast if((crtStatus[neighbourOffset].is_contrast_labeled == NOTLABELED) && ((*(pInputIm + neighbourOffset)) != (*(pInputIm + offset)))){ fifo4_add(cq, neighbourOffset); crtStatus[neighbourOffset].is_contrast_labeled = LABELED; countContrastPixel++; } } } } //determine the region contrast koeffizient //take all Pixel which surrounds the region and sum up the contrast values while(fifo4_empty(cq) == 0){ offset = (long int) fifo4_remove(cq); distance =rmGetDistanceToRM(&rm, imap, offset); contrast+= distance; crtStatus[neighbourOffset].is_contrast_labeled = NOTLABELED; } contrast/=(double) countContrastPixel; //contrast = fabs(contrast); //all pixel belonging to the same region are stored in the rq. //Process now according to threshold value //printf("contrast: %f\n", contrast); if((threshold == 0)){ while (fifo4_empty(rq) == 0){ offset = (long int) fifo4_remove(rq); (*(pInputIm + offset)) = contrast; } label++; } else if (contrast>=threshold){ while (fifo4_empty(rq) == 0){ offset = (long int) fifo4_remove(rq); (*(pInputIm + offset)) = label; } label++; }else{ while(fifo4_empty(rq) == 0){ offset = (long int)fifo4_remove(rq); (*(pInputIm + offset)) = 0; } } } } free_fifo4(nq); free_fifo4(rq); free_fifo4(cq); freeRegionMean(&rm); free(crtStatus); for(i=0; i=0){ return (label-1); } else{ return NO_ERROR; } } jeolib-miallib-1.1.6/core/c/determineSize.h000066400000000000000000000030371467232417700205440ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** determineSize.h - description ------------------- begin : Tue APR 13 2004 ***************************************************************************/ #ifndef init_determineSize #define init_determineSize #include "miallib.h" #define SIZE 0x01 #define CONTRAST 0x02 long int thresholdRegion_Size(IMAGE *inputIm, unsigned long int threshold); ERROR_TYPE thresholdImage(IMAGE *inputIm, unsigned long int threshold); long int thresholdRegion_Contrast(IMAGE **imap, int nc, IMAGE * inputIm, unsigned long int threshold); #endif jeolib-miallib-1.1.6/core/c/dirmean.c000066400000000000000000000163251467232417700173530ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" /** @defgroup group_miscel miscellaneous operations * Miscellaneous image transformations not matching the other modules. * @{ */ #define rad2deguchar(x) ((x)*((double)255/(2*PI))) /* radians to uchar values */ #define PIX_TYPE UCHAR IMAGE *dirmean(IMAGE *imx, IMAGE *imy, IMAGE *imse, int ox, int oy, int oz) { /* see thesis by Alan Hanbury and book by Rao */ IMAGE *imout; int box[BOXELEM]; int n, nx, ny, nz; long int *shft, num, den, dx, dy; INT32 *px, *py; UCHAR *pori; long int k, x, y, z; long int lstx, lsty, lstz; nx = GetImNx(imx); ny = GetImNy(imx); nz = GetImNz(imx); /* create shift array */ n = objectpix(imse); if (n==ERROR) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((unsigned char *)GetImPtr(imse), box, GetImNx(imx), GetImNy(imx), shft); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; /* create output image */ imout = (IMAGE *)create_image(t_UCHAR, GetImNx(imx), GetImNy(imx), GetImNz(imx)); if (imout == NULL){ free(shft); (void)sprintf(buf,"dirmean(): not enough memory!\n"); errputstr(buf); return(imout); } px=(INT32 *)GetImPtr(imx); py=(INT32 *)GetImPtr(imy); pori=(UCHAR *)GetImPtr(imout); for (z = box[4]; z < lstz; z++){ px = px + nx * ny * z; px += nx * box[2]; px += box[0]; py = py + nx * ny * z; py += nx * box[2]; py += box[0]; pori = pori + nx * ny * z; pori += nx * box[2]; pori += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ num =0; den =0; for (k = 0; k < n; k++){ dx = *(px+shft[k]); dy = *(py+shft[k]); num += dx * dy; den += dx*dx - dy*dy; } if (den<0){ *pori=(PIX_TYPE)rad2deguchar(PI+atan((double)2.0 * num/den)); } else if (den==0){ if (num>0){ *pori=(PIX_TYPE)rad2deguchar(PI/2); } else{ *pori=(PIX_TYPE)rad2deguchar(3*PI/2); } } else if (num<0){ *pori=(PIX_TYPE)rad2deguchar(2*PI+atan((double)2.0 * num/den)); } else{ *pori=(PIX_TYPE)rad2deguchar(atan((double)2.0 * num/den)); } pori++; px++; py++; } pori += box[0] + box[1]; px += box[0] + box[1]; py += box[0] + box[1]; } } free_image(imx); free_image(imy); free((char *) shft); return(imout); } #undef PIX_TYPE #undef rad2deguchar #define rad2deguchar(x) ((x)*((double)255/(2*PI))) /* radians to uchar values */ #define PIX_TYPE UCHAR IMAGE *coherence(IMAGE *imx, IMAGE *imy, IMAGE *imse, int ox, int oy, int oz) { /* see thesis by Alan Hanbury and book by Rao */ IMAGE *imout, *imori; UCHAR *pcoh; int box[BOXELEM]; int n, nx, ny, nz; long int *shft, dx, dy; INT32 *px, *py; DOUBLE *pori; long int k, x, y, z; long int lstx, lsty, lstz; double theta, mag, den, num; nx = GetImNx(imx); ny = GetImNy(imx); nz = GetImNz(imx); /* create shift array */ n = objectpix(imse); if (n==ERROR) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((unsigned char *)GetImPtr(imse), box, GetImNx(imx), GetImNy(imx), shft); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; /* create image for mean orientation */ imori = (IMAGE *)create_image(t_DOUBLE, GetImNx(imx), GetImNy(imx), GetImNz(imx)); if (imori == NULL){ free(shft); (void)sprintf(buf,"dirmean(): not enough memory!\n"); errputstr(buf); return(imori); } /* create output image */ imout = (IMAGE *)create_image(t_UCHAR, GetImNx(imx), GetImNy(imx), GetImNz(imx)); if (imout == NULL){ free(shft); free_image(imori); (void)sprintf(buf,"dirmean(): not enough memory!\n"); errputstr(buf); return(imout); } /* compute first mean orientation */ px=(INT32 *)GetImPtr(imx); py=(INT32 *)GetImPtr(imy); pori=(DOUBLE *)GetImPtr(imori); for (z = box[4]; z < lstz; z++){ px = px + nx * ny * z; px += nx * box[2]; px += box[0]; py = py + nx * ny * z; py += nx * box[2]; py += box[0]; pori = pori + nx * ny * z; pori += nx * box[2]; pori += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ num=0.0; den=0.0; for (k = 0; k < n; k++){ dx = *(px+shft[k]); dy = *(py+shft[k]); num += dx * dy; den += dx*dx - dy*dy; } if (den==0){ *pori=0.5 * PI/2; } else{ *pori=0.5 * atan(2.0 * num/den); } pori++; px++; py++; } pori += box[0] + box[1]; px += box[0] + box[1]; py += box[0] + box[1]; } } /* now compute coherence */ px=(INT32 *)GetImPtr(imx); py=(INT32 *)GetImPtr(imy); pori=(DOUBLE *)GetImPtr(imori); pcoh=(UCHAR *)GetImPtr(imout); for (z = box[4]; z < lstz; z++){ px = px + nx * ny * z; px += nx * box[2]; px += box[0]; py = py + nx * ny * z; py += nx * box[2]; py += box[0]; pori = pori + nx * ny * z; pori += nx * box[2]; pori += box[0]; pcoh = pcoh + nx * ny * z; pcoh += nx * box[2]; pcoh += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ den=0; num=0; for (k = 0; k < n; k++){ dx = *(px+shft[k]); dy = *(py+shft[k]); if (dx<0){ theta=PI+atan((double)dy/dx); } else if (dx==0){ if (dy>0){ theta=PI/2; } else{ theta=3*PI/2; } } else if (dy<0){ theta=2*PI+atan((double)dy/dx); } else theta=atan((double)dy/dx); mag=sqrt( (double) dx*dx + dy*dy ); num+=fabs(mag * cos(*pori - theta)); den+=mag; if ( (x>800) && (x<810)) if ((y>190) && (y<200) ) printf("x=%ld, y=%ld, *pori=%f, theta=%f, num=%f, den=%f\n", x, y, (float)*pori, (float)theta, (float)num, (float)den); } *pcoh=(UCHAR) ( 255.0 * num/den ); pcoh++; pori++; px++; py++; } pcoh += box[0] + box[1]; pori += box[0] + box[1]; px += box[0] + box[1]; py += box[0] + box[1]; } } free_image(imori); free_image(imx); free_image(imy); free((char *) shft); return(imout); } /**@}*/ #undef PIX_TYPE #undef rad2deguchar jeolib-miallib-1.1.6/core/c/dist.c000066400000000000000000000512671467232417700167030ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Functions dealing with distance calculations inlcuding geodesic distances and influence zones. * For the Euclidean distance function edistfifo2d using a FIFO, see \cite soille91 * @author Pierre Soille */ #include #include #include #include "miallib.h" /** @defgroup group_dist Distance and distance based functions * Functions dealing with distance calculations inlcuding geodesic distances and influence zones. * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_dst2d4(IMAGE *im) { int box[BOXELEM]; PIX_TYPE *p, *pend, tmp; int nx = GetImNx(im); /* Set borders to zero */ box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; if (generic_framebox(im,box,0)==ERROR) return ERROR; /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+nx*GetImNy(im)-GetImNx(im)-1; for (p += (nx + 1); p < pend; ++p){ if (*p) *p = (*(p-1)+1)<(*(p-nx)+1) ? *(p-1)+1 : *(p-nx)+1; } /* backward scan */ pend = (PIX_TYPE *)GetImPtr(im)+GetImNx(im); p = (PIX_TYPE *)GetImPtr(im)+nx*GetImNy(im); for (p -= (GetImNx(im)-2); p > pend; --p){ if (*p){ tmp = *p; *p = (*(p+1)+1) < (*(p+nx)+1) ? *(p+1)+1 : *(p+nx)+1; if (tmp < *p) *p = tmp; } } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_dst2d4(IMAGE *im) { int box[BOXELEM]; PIX_TYPE *p, *pend, tmp; int nx = GetImNx(im); /* Set borders to zero */ box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; if (us_framebox(im,box,0)==ERROR) return ERROR; /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+nx*GetImNy(im)-GetImNx(im)-1; for (p += (nx + 1); p < pend; ++p){ if (*p) *p = (*(p-1)+1)<(*(p-nx)+1) ? *(p-1)+1 : *(p-nx)+1; } /* backward scan */ pend = (PIX_TYPE *)GetImPtr(im)+GetImNx(im); p = (PIX_TYPE *)GetImPtr(im)+nx*GetImNy(im); for (p -= (GetImNx(im)-2); p > pend; --p){ if (*p){ tmp = *p; *p = (*(p+1)+1) < (*(p+nx)+1) ? *(p+1)+1 : *(p+nx)+1; if (tmp < *p) *p = tmp; } } return(NO_ERROR); } #include "us_undef.h" ERROR_TYPE dst2d4(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_dst2d4(im)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_dst2d4(im)); break; #endif case t_USHORT: return(us_dst2d4(im)); break; default: (void)sprintf(buf,"dst2d4(im): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_dst2dchamfer(IMAGE *im) { int box[BOXELEM]; PIX_TYPE *p, *pend; int nx = GetImNx(im); /* Set borders to zero */ box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; if (generic_framebox(im,box,0)==ERROR) return ERROR; /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+nx*GetImNy(im)-GetImNx(im)-1; for (p += (nx + 1); p < pend; ++p){ if (*p){ *p = *(p - nx + 1) + 7; if (*p > *(p - nx) + 5) *p = *(p - nx) + 5; if (*p > *(p - nx - 1) + 7) *p = *(p - nx - 1) + 7; if (*p > *(p - 1) + 5) *p = *(p - 1) + 5; } } /* backward scan */ pend = (PIX_TYPE *)GetImPtr(im)+GetImNx(im); p = (PIX_TYPE *)GetImPtr(im)+nx*GetImNy(im); for (p -= (GetImNx(im)-2); p > pend; --p){ if (*p){ if (*p > *(p + nx + 1) + 7) *p = *(p + nx + 1) + 7; if (*p > *(p + nx) + 5) *p = *(p + nx) + 5; if (*p > *(p + nx - 1) + 7) *p = *(p + nx - 1) + 7; if (*p > *(p + 1) + 5) *p = *(p + 1) + 5; } } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_dst2dchamfer(IMAGE *im) { int box[BOXELEM]; PIX_TYPE *p, *pend; int nx = GetImNx(im); /* Set borders to zero */ box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; if (us_framebox(im,box,0)==ERROR) return ERROR; /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+nx*GetImNy(im)-GetImNx(im)-1; for (p += (nx + 1); p < pend; ++p){ if (*p){ *p = *(p - nx + 1) + 7; if (*p > *(p - nx) + 5) *p = *(p - nx) + 5; if (*p > *(p - nx - 1) + 7) *p = *(p - nx - 1) + 7; if (*p > *(p - 1) + 5) *p = *(p - 1) + 5; } } /* backward scan */ pend = (PIX_TYPE *)GetImPtr(im)+GetImNx(im); p = (PIX_TYPE *)GetImPtr(im)+nx*GetImNy(im); for (p -= (GetImNx(im)-2); p > pend; --p){ if (*p){ if (*p > *(p + nx + 1) + 7) *p = *(p + nx + 1) + 7; if (*p > *(p + nx) + 5) *p = *(p + nx) + 5; if (*p > *(p + nx - 1) + 7) *p = *(p + nx - 1) + 7; if (*p > *(p + 1) + 5) *p = *(p + 1) + 5; } } return(NO_ERROR); } #include "us_undef.h" ERROR_TYPE dst2dchamfer(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_dst2dchamfer(im)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_dst2dchamfer(im)); break; #endif case t_USHORT: return(us_dst2dchamfer(im)); break; default: (void)sprintf(buf,"dst2dchamfer(im): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /* Euclidean FIFO distance transform: quick and dirty from GRIMAGE */ #include "fifo.h" /* ** */ ERROR_TYPE setdxdy(int *dx, int *dy, int graph) { if (graph == 4){ dx[0] = 0; dy[0] = 1; dx[1] = 1; dy[1] = 0; dx[2] = 0; dy[2] = 1; dx[3] = 1; dy[3] = 0; } else if (graph == 8){ dx[0] = 0; dy[0] = 1; dx[1] = 1; dy[1] = 0; dx[2] = 1; dy[2] = 1; dx[3] = 1; dy[3] = 1; dx[4] = 1; dy[4] = 0; dx[5] = 0; dy[5] = 1; dx[6] = 1; dy[6] = 1; dx[7] = 1; dy[7] = 1; } else return ERROR; return NO_ERROR; } /* ** Function to initialize a queue with contour pixels. */ ERROR_TYPE cqentercontour(IMAGE *im, int obj, int bgd, int graph, int inqueue, FIFO4 *q) { long int k, shift, shft[27]; if (set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shft) != NO_ERROR) return ERROR; switch (GetImDataType(im)){ case t_UCHAR: { UCHAR *p; UCHAR *p_end = (UCHAR *)GetImPtr(im) + GetImNx(im)*GetImNy(im); for (k = 0; k < graph; ++k){ shift = shft[k]; p = (UCHAR *)GetImPtr(im); for (; p < p_end; ++p){ if (*p == obj){ if (*(p + shift) == bgd){ fifo4_add(q, (long int)p); *p = inqueue; } } } } break; } case t_USHORT: { USHORT *p; USHORT *p_end = (USHORT *)GetImPtr(im) + GetImNx(im)*GetImNy(im); for (k = 0; k < graph; ++k){ shift = shft[k]; p = (USHORT *)GetImPtr(im); for (; p < p_end; ++p){ if (*p == obj){ if (*(p + shift) == bgd){ fifo4_add(q, (long int)p); *p = inqueue; } } } } break; } default: return ERROR; } return NO_ERROR; } /* distance function using a FIFO \cite soille91 */ #include "us_def.h" /* for output */ IMAGE *edistfifo2d(IMAGE *im, int graph) { long int dmin, dp, dcrt, dpx, dpy, max_dist = INT32_MAX-1; int dx[8], dy[8], k; PIX_TYPE *p, *px, *py, *ptr; PIX_TYPE pmaxm1=PIX_MAX-1; FIFO4 *q; IMAGE *imn, *imw; long int shft[27]; int box[6]; if (set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shft) != NO_ERROR) return NULL; if (setdxdy(dx, dy, graph) != NO_ERROR) return NULL; imn = (IMAGE *)to_ushort(im); if (imn==NULL) return NULL; us_setlevel(imn, 1, 1, PIX_MAX); box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; us_framebox(imn, box, PIX_MAX-1); imw=copy_image(imn); if (imn==NULL){ (void) sprintf(buf, "eudistance(): not enough memory"); errputstr(buf); free_image(imn); return NULL; } q = create_fifo4(1000L); if (q == NULL){ (void) sprintf(buf, "eudistance(): not enough memory"); errputstr(buf); free_image(imn); free_image(imw); return NULL; } if (cqentercontour(imn, PIX_MAX, 0, graph, PIX_MAX - 1, q) != NO_ERROR){ free_image(imn); free_image(imw); free_fifo4(q); return NULL; } px = (PIX_TYPE *)GetImPtr(imn); py = (PIX_TYPE *)GetImPtr(imw); while (fifo4_empty(q) == FALSE){ fifo4_add(q,(long int)FICT_PIX); q->qpl= q->qpr; dmin = max_dist; while ((p = (PIX_TYPE *) fifo4_look(q)) != (PIX_TYPE *)FICT_PIX){ dp = max_dist; if (*p < pmaxm1) continue; for (k = 0; k < graph; ++k){ if ((*(ptr = p + shft[k]) < pmaxm1)){ dpx = *ptr + dx[k]; dpy = py[ptr - px] + dy[k]; dcrt = dpx * dpx + dpy * dpy; if (dcrt < dp){ *p = dpx; py[p - px] = dpy; dp = dcrt; } } } if (dmin > dp) dmin = dp; } while ((p = (PIX_TYPE *)fifo4_remove(q)) != (PIX_TYPE *)FICT_PIX){ if (SQ((int)*p) + SQ((int)py[p - px]) > dmin) fifo4_add(q,(long int)p); else{ for (k = 0; k < graph; ++k){ if (*(ptr = p + shft[k]) == PIX_MAX){ fifo4_add(q,(long int)ptr); *ptr = pmaxm1; } } } } } free_fifo4(q); us_framebox(imn, box, 0); LOOPDN(k, GetImNPix(imn) - 1){ *px = (PIX_TYPE)sqrt((double)(SQ((int)*px) + SQ((int)*py))); px++; py++; } free_image(imw); return imn; } #include "us_undef.h" /* *************************************************** */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_chamfer2d(IMAGE *im, int type) { int box[BOXELEM]; int *shft, n, k; PIX_TYPE *dval, dcrt; PIX_TYPE *p, *pend; /* Set borders to zero */ switch (type){ case 1: /* city-block or 4-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; generic_addframebox(im, box, 0); n=2; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im); dval[0]=1; shft[1]=-1; dval[1]=1; break; case 11: /* chess-board or 8-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; generic_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=1; shft[1]=-GetImNx(im); dval[1]=1; shft[2]=-GetImNx(im)+1; dval[2]=1; shft[3]=-1; dval[3]=1; break; case 34: /* 3-4 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; generic_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=4; shft[1]=-GetImNx(im); dval[1]=3; shft[2]=-GetImNx(im)+1; dval[2]=4; shft[3]=-1; dval[3]=3; break; case 57: /* 5-7 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; generic_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=7; shft[1]=-GetImNx(im); dval[1]=5; shft[2]=-GetImNx(im)+1; dval[2]=7; shft[3]=-1; dval[3]=5; break; case 5711: /* 5-7-11 chamfer distance */ box[0]=2; box[1]=2; box[2]=2; box[3]=2; box[4]=0; box[5]=0; generic_addframebox(im, box, 0); n=8; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-(2*GetImNx(im))-1; dval[0]=11; shft[1]=-(2*GetImNx(im))+1; dval[1]=11; shft[2]=-GetImNx(im)-2; dval[2]=11; shft[3]=-GetImNx(im)-1; dval[3]=7; shft[4]=-GetImNx(im); dval[4]=5; shft[5]=-GetImNx(im)+1; dval[5]=7; shft[6]=-GetImNx(im)+2; dval[6]=11; shft[7]=-1; dval[7]=5; break; default: (void)sprintf(buf,"generic_chamfer2d(): Invalid chamfer type"); errputstr(buf); return(ERROR); } /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+GetImNx(im)*GetImNy(im)-GetImNx(im)*box[0]-box[0]; for (p += (box[0]*GetImNx(im) + box[0]); p < pend; ++p){ if (*p){ *p = *(p+*shft)+*dval; for (k=1; k dcrt) *p = dcrt; } } } /* backward scan */ for (k=0; k pend; --p){ if (*p){ for (k=0; k dcrt) *p = dcrt; } } } subframebox(im, box); free((char *)dval); free((char *)shft); return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_chamfer2d(IMAGE *im, int type) { int box[BOXELEM]; int *shft, n, k; PIX_TYPE *dval, dcrt; PIX_TYPE *p, *pend; /* Set borders to zero */ switch (type){ case 1: /* city-block or 4-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; us_addframebox(im, box, 0); n=2; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im); dval[0]=1; shft[1]=-1; dval[1]=1; break; case 11: /* chess-board or 8-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; us_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=1; shft[1]=-GetImNx(im); dval[1]=1; shft[2]=-GetImNx(im)+1; dval[2]=1; shft[3]=-1; dval[3]=1; break; case 34: /* 3-4 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; us_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=4; shft[1]=-GetImNx(im); dval[1]=3; shft[2]=-GetImNx(im)+1; dval[2]=4; shft[3]=-1; dval[3]=3; break; case 57: /* 5-7 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; us_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=7; shft[1]=-GetImNx(im); dval[1]=5; shft[2]=-GetImNx(im)+1; dval[2]=7; shft[3]=-1; dval[3]=5; break; case 5711: /* 5-7-11 chamfer distance */ box[0]=2; box[1]=2; box[2]=2; box[3]=2; box[4]=0; box[5]=0; us_addframebox(im, box, 0); n=8; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-(2*GetImNx(im))-1; dval[0]=11; shft[1]=-(2*GetImNx(im))+1; dval[1]=11; shft[2]=-GetImNx(im)-2; dval[2]=11; shft[3]=-GetImNx(im)-1; dval[3]=7; shft[4]=-GetImNx(im); dval[4]=5; shft[5]=-GetImNx(im)+1; dval[5]=7; shft[6]=-GetImNx(im)+2; dval[6]=11; shft[7]=-1; dval[7]=5; break; default: (void)sprintf(buf,"us_chamfer2d(): Invalid chamfer type"); errputstr(buf); return(ERROR); } /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+GetImNx(im)*GetImNy(im)-GetImNx(im)*box[0]-box[0]; for (p += (box[0]*GetImNx(im) + box[0]); p < pend; ++p){ if (*p){ *p = *(p+*shft)+*dval; for (k=1; k dcrt) *p = dcrt; } } } /* backward scan */ for (k=0; k pend; --p){ if (*p){ for (k=0; k dcrt) *p = dcrt; } } } subframebox(im, box); free((char *)dval); free((char *)shft); return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_chamfer2d(IMAGE *im, int type) { int box[BOXELEM]; int *shft, n, k; PIX_TYPE *dval, dcrt; PIX_TYPE *p, *pend; /* Set borders to zero */ switch (type){ case 1: /* city-block or 4-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; i32_addframebox(im, box, 0); n=2; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im); dval[0]=1; shft[1]=-1; dval[1]=1; break; case 11: /* chess-board or 8-connected distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; i32_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=1; shft[1]=-GetImNx(im); dval[1]=1; shft[2]=-GetImNx(im)+1; dval[2]=1; shft[3]=-1; dval[3]=1; break; case 34: /* 3-4 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; i32_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=4; shft[1]=-GetImNx(im); dval[1]=3; shft[2]=-GetImNx(im)+1; dval[2]=4; shft[3]=-1; dval[3]=3; break; case 57: /* 5-7 chamfer distance */ box[0]=1; box[1]=1; box[2]=1; box[3]=1; box[4]=0; box[5]=0; i32_addframebox(im, box, 0); n=4; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-GetImNx(im)-1; dval[0]=7; shft[1]=-GetImNx(im); dval[1]=5; shft[2]=-GetImNx(im)+1; dval[2]=7; shft[3]=-1; dval[3]=5; break; case 5711: /* 5-7-11 chamfer distance */ box[0]=2; box[1]=2; box[2]=2; box[3]=2; box[4]=0; box[5]=0; i32_addframebox(im, box, 0); n=8; shft =(int *)calloc(n, sizeof(int)); dval =(PIX_TYPE *)calloc(n, sizeof(PIX_TYPE)); shft[0]=-(2*GetImNx(im))-1; dval[0]=11; shft[1]=-(2*GetImNx(im))+1; dval[1]=11; shft[2]=-GetImNx(im)-2; dval[2]=11; shft[3]=-GetImNx(im)-1; dval[3]=7; shft[4]=-GetImNx(im); dval[4]=5; shft[5]=-GetImNx(im)+1; dval[5]=7; shft[6]=-GetImNx(im)+2; dval[6]=11; shft[7]=-1; dval[7]=5; break; default: (void)sprintf(buf,"us_chamfer2d(): Invalid chamfer type"); errputstr(buf); return(ERROR); } /* forward scan */ p = (PIX_TYPE *)GetImPtr(im); pend = p+GetImNx(im)*GetImNy(im)-GetImNx(im)*box[0]-box[0]; for (p += (box[0]*GetImNx(im) + box[0]); p < pend; ++p){ if (*p){ *p = *(p+*shft)+*dval; for (k=1; k dcrt) *p = dcrt; } } } /* backward scan */ for (k=0; k pend; --p){ if (*p){ for (k=0; k dcrt) *p = dcrt; } } } subframebox(im, box); free((char *)dval); free((char *)shft); return(NO_ERROR); } #include "i32_undef.h" ERROR_TYPE chamfer2d(IMAGE *im, int type) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_chamfer2d(im, type)); break; #endif case t_USHORT: return(us_chamfer2d(im, type)); break; case t_INT32: return(i32_chamfer2d(im, type)); break; default: (void)sprintf(buf,"chamfer2d(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /*@}*/ jeolib-miallib-1.1.6/core/c/douglas-peucker.c000066400000000000000000000143761467232417700210320ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** simplifyLine.c - description ------------------- Implementation of the douglas peucker line simplifiaction algorithm begin : Wed Jun 16 2004 ***************************************************************************/ #include #include #include struct STACK_RECORD { int nAnchorIndex, nFloaterIndex; struct STACK_RECORD *precPrev; } *m_pStack; /* * StackPush: Push point on the stack * * Parameters: * * nAnchorIndex anchor index * * nFloaterIndex floater index * * Return values: * * none */ void StackPush( int nAnchorIndex, int nFloaterIndex ) { struct STACK_RECORD *precPrev = m_pStack; m_pStack = (struct STACK_RECORD *)malloc( sizeof(struct STACK_RECORD) ); m_pStack->nAnchorIndex = nAnchorIndex; m_pStack->nFloaterIndex = nFloaterIndex; m_pStack->precPrev = precPrev; } /* * StackPush: Pop point from the stack * * Parameters: * * pnAnchorIndex pointer to an anchor index (result of pop is stored here) * * pnFloaterIndex pointer to a floater index (result of pop is stored here) * * Return values: * * 0 if global stack is NULL * * 1 if everything is ok */ int StackPop( int *pnAnchorIndex, int *pnFloaterIndex ) { struct STACK_RECORD *precStack = m_pStack; if ( precStack == NULL ) return 0; //false *pnAnchorIndex = precStack->nAnchorIndex; *pnFloaterIndex = precStack->nFloaterIndex; m_pStack = precStack->precPrev; free( precStack ); return 1; //true } /* * ReducePoints: Reduces points of a line using the douglas peucker algorithm * * Parameters: * * pPointsX Array of x coordinates of the line * * pPointsY Array of y coordinates of the line * * pPointsCount Number of points in the line * * pnUseFlag Array of flags whether a point needs to be used in order to display the line or not * * tolerance parameter for the simplification of the line. The higher the value * the more will the line be simplified. * * Return values: * * none */ void ReducePoints( double *pPointsX, double *pPointsY, int nPointsCount, int *pnUseFlag, double dTolerance) { int nVertexIndex, nAnchorIndex, nFloaterIndex; double dSegmentVecLength; double dAnchorVecX, dAnchorVecY; double dAnchorUnitVecX, dAnchorUnitVecY; double dVertexVecLength; double dVertexVecX, dVertexVecY; double dProjScalar; double dVertexDistanceToSegment; double dMaxDistThisSegment; int nVertexIndexMaxDistance; nAnchorIndex = 0; nFloaterIndex = nPointsCount - 1; StackPush( nAnchorIndex, nFloaterIndex ); while ( StackPop( &nAnchorIndex, &nFloaterIndex ) ){ // initialize line segment dAnchorVecX = pPointsX[ nFloaterIndex ] - pPointsX[ nAnchorIndex ]; dAnchorVecY = pPointsY[ nFloaterIndex ] - pPointsY[ nAnchorIndex ]; dSegmentVecLength = sqrt( dAnchorVecX * dAnchorVecX + dAnchorVecY * dAnchorVecY ); dAnchorUnitVecX = dAnchorVecX / dSegmentVecLength; dAnchorUnitVecY = dAnchorVecY / dSegmentVecLength; // inner loop: dMaxDistThisSegment = 0.0; nVertexIndexMaxDistance = nAnchorIndex + 1; for ( nVertexIndex = nAnchorIndex + 1; nVertexIndex < nFloaterIndex; nVertexIndex++ ){ //compare to anchor dVertexVecX = pPointsX[ nVertexIndex ] - pPointsX[ nAnchorIndex ]; dVertexVecY = pPointsY[ nVertexIndex ] - pPointsY[ nAnchorIndex ]; dVertexVecLength = sqrt( dVertexVecX * dVertexVecX + dVertexVecY * dVertexVecY ); //dot product: dProjScalar = dVertexVecX * dAnchorUnitVecX + dVertexVecY * dAnchorUnitVecY; if ( dProjScalar < 0.0 ) dVertexDistanceToSegment = dVertexVecLength; else{ //compare to floater dVertexVecX = pPointsX[ nVertexIndex ] - pPointsX[ nFloaterIndex ]; dVertexVecY = pPointsY[ nVertexIndex ] - pPointsY[ nFloaterIndex ]; dVertexVecLength = sqrt( dVertexVecX * dVertexVecX + dVertexVecY * dVertexVecY ); //dot product: dProjScalar = dVertexVecX * (-dAnchorUnitVecX) + dVertexVecY * (-dAnchorUnitVecY); if ( dProjScalar < 0.0 ) dVertexDistanceToSegment = dVertexVecLength; else //calculate perpendicular distance to line (pythagorean theorem): dVertexDistanceToSegment = sqrt( fabs( dVertexVecLength * dVertexVecLength - dProjScalar * dProjScalar ) ); } //else if ( dMaxDistThisSegment < dVertexDistanceToSegment ){ dMaxDistThisSegment = dVertexDistanceToSegment; nVertexIndexMaxDistance = nVertexIndex; } //if } //for (inner loop) if ( dMaxDistThisSegment <= dTolerance ){ //use line segment pnUseFlag[ nAnchorIndex ] = 1; pnUseFlag[ nFloaterIndex ] = 1; } //if use points else{ StackPush( nAnchorIndex, nVertexIndexMaxDistance ); StackPush( nVertexIndexMaxDistance, nFloaterIndex ); } //else } } jeolib-miallib-1.1.6/core/c/douglas-peucker.h000066400000000000000000000025331467232417700210270ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** douglas-peucker.h - description ------------------- begin : Wed Jun 16 2004 ***************************************************************************/ #ifndef init_douglas_peucker #define init_douglas_peucker void ReducePoints( double *pPointsX, double *pPointsY, int nPointsCount, int *pnUseFlag, double dTolerance ); #endif jeolib-miallib-1.1.6/core/c/edgeweight.c000066400000000000000000000104331467232417700200420ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2010-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file edgeweight.c * @author Pierre SOILLE * @date Mon Oct 18 14:00:02 2010 * * @details See also \cite soille2011ismm * */ /* first 20101018 */ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif #include "uc_def.h" #define RANGE 0 #define MAXVAL 1 #define MINVAL 2 IMAGE *uc_edgeweight(IMAGE *im, int dir, int type) { IMAGE *imout; PIX_TYPE *pin, *pout; int nx=GetImNx(im), nxout; int ny=GetImNy(im), nyout; long int x, y; int nxlast, nylast; int shft; nxout=nx; nyout=ny; if (dir==0){ // horizontal nxlast=nx-1; nylast=ny; shft=1; } else{ // vertical nxlast=nx; nylast=ny-1; shft=nx; } imout=create_image(GetImDataType(im), nxout, nyout, 1); if (imout == NULL){ return NULL; } pin=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); switch(type){ case RANGE: #ifdef OPENMP #pragma omp parallel for private(x) #endif for (y=0; y. ***********************************************************************/ /* error free Euclidean distance (squared values) following the pseudo-code of Meijster-Roerdink-Hesselink (2000) (original idea in Saito and Toriwaki, 1994). We compute the distance function on the foreground pixels, i.e., those different from 0. first: 2003-11-25 2nd last: 2003-11-28 (with influence zones) last: 2013 added omp speed-up 20131001: changed INT32 to USHORT for the images imx and imy */ /** @file * Error free Euclidean distance transform (square of) following the pseudo-code described in * \cite meijster-roerdink-hesselink2000 following the original idea of \cite saito-toriwaki94 * @author Pierre Soille * */ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif #define NORM(x,y) ( ((x)*(x)) + ((y)*(y)) ) #define NORMU(x,y) ( (((UINT64)x)*((UINT64)x)) + (((UINT64)y)*((UINT64)y)) ) #define SQU(x) ( ((UINT64)x) * ((UINT64)x) ) /** \addtogroup group_dist * @{ */ #define EFEDT_G_IS_UINT32 1 #include "uc_def.h" #ifdef EFEDT_G_IS_UINT32 #define GTYPE UINT32 #define t_GTYPE t_UINT32 #define GTYPE_MAX UINT32_MAX #define BIGVAL (GTYPE_MAX/2) #else #define GTYPE USHORT #define t_GTYPE t_USHORT #define GTYPE_MAX USHORT_MAX #define BIGVAL (GTYPE_MAX/2) #endif #define DTYPE UINT32 #define t_DTYPE t_UINT32 IMAGE *uc_sqedt(IMAGE *im) { IMAGE *img, *imdt; PIX_TYPE *b; GTYPE *g, bigval; DTYPE *dt; long int *t, *s; long long int x, y, w, m, n, q, sep; unsigned long int offset, yxm; m=GetImNx(im); n=GetImNy(im); /* ursprunglich!!! bigval=m+n and mit fixed Type UINT32; geaendert am 20131002 for USHORT */ bigval=BIGVAL; /* create temporary and output images */ img = create_image(t_GTYPE, GetImNx(im), GetImNy(im), GetImNz(im)); if (img == NULL){ (void)sprintf(buf,"IMAGE *uc_sqedt(IMAGE *im): not enough memory!\n"); errputstr(buf); return(NULL); } imdt = create_image(t_DTYPE, GetImNx(im), GetImNy(im), GetImNz(im)); if (imdt == NULL){ (void)sprintf(buf,"IMAGE *uc_sqedt(IMAGE *im): not enough memory!\n"); errputstr(buf); free_image(img); return(NULL); } /* create t and s arrays */ #ifndef OPENMP t = (long int *)calloc(sizeof(long int), m); s = (long int *)calloc(sizeof(long int), m); #endif b=(PIX_TYPE *)GetImPtr(im); g=(GTYPE *)GetImPtr(img); dt=(DTYPE *)GetImPtr(imdt); /* scans 1 and 2 */ #ifdef OPENMP #pragma omp parallel for private(x,offset,y) #endif for (x=0; x=0; y--){ /* backward column scan */ offset=x+y*m; if ( *(g+offset+m) < *(g+offset) ) *(g+offset)=1+*(g+offset+m); } } /* scans 3 and 4 */ #ifdef OPENMP #pragma omp parallel for private(t,s,yxm,q,x,sep,w) #endif for (y=0; y=0) && (NORMU(t[q]-s[q],*(g+s[q]+yxm)) > NORMU(t[q]-x,*(g+x+yxm))) ) q--; if (q<0){ q=0; s[0]=x; } else{ sep=(SQU(x)-SQU(s[q])+SQU(*(g+x+yxm))-SQU(*(g+s[q]+yxm))) / (2*(x-s[q])); w=1+ sep; if (w=0; x--){ *(dt+x+yxm)=NORMU(x-s[q],*(g+s[q]+yxm)); if( x==t[q] ) q--; } #ifdef OPENMP free(s); free(t); #endif } #ifndef OPENMP free(s); free(t); #endif free_image(img); return(imdt); } #undef BIGVAL #undef GTYPE #undef t_GTYPE #undef DTYPE #undef t_DTYPE #undef GTYPE_MAX #include "uc_undef.h" IMAGE *sqedt(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return (uc_sqedt(im)); break; default: (void)sprintf(buf,"sqedt(im): invalid pixel type: im must be of type UCHAR\n"); errputstr(buf); return(NULL); } return NULL; } #include "uc_def.h" #ifdef EFEDT_G_IS_UINT32 #define GTYPE UINT32 #define t_GTYPE t_UINT32 #define GTYPE_MAX UINT32_MAX #define BIGVAL (m+n) #else #define GTYPE USHORT #define t_GTYPE t_USHORT #define GTYPE_MAX USHORT_MAX #define BIGVAL (GTYPE_MAX/2) #endif IMAGE *uc_iz(IMAGE *im) { IMAGE *img, *imiz; PIX_TYPE *b, *iz; GTYPE *g, bigval; long int *t, *s; int x, y, w, m, n, q, sep; long int i; unsigned long int offset, yxm; m=GetImNx(im); n=GetImNy(im); bigval=BIGVAL; /* make sure the MSB of the input image is always equal to zero (this bit is used for the internal computations) */ b=(PIX_TYPE *)GetImPtr(im); for(i=m*n; i>0; i--) if (*b++ >= PIX_MSB){ (void)sprintf(buf,"IMAGE *uc_iz(IMAGE *im): the image values must be <=127 (2^7 - 1)!\n"); errputstr(buf); return(NULL); } /* create temporary and output images */ img = create_image(t_GTYPE, GetImNx(im), GetImNy(im), GetImNz(im)); if (img == NULL){ (void)sprintf(buf,"IMAGE *uc_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); return(NULL); } imiz = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imiz == NULL){ (void)sprintf(buf,"IMAGE *uc_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); free_image(img); return(NULL); } #ifndef OPENMP /* create t and s arrays */ t = (long int *)calloc(sizeof(long int), m); s = (long int *)calloc(sizeof(long int), m); #endif b=(PIX_TYPE *)GetImPtr(im); g=(GTYPE *)GetImPtr(img); iz=(PIX_TYPE *)GetImPtr(imiz); /* scans 1 and 2 */ #ifdef OPENMP #pragma omp parallel for private(x,offset,y) #endif for (x=0; x=0; y--){ /* backward column scan */ offset=x+y*m; if ( *(g+offset+m) < *(g+offset) ){ *(g+offset)=1+*(g+offset+m); *(b+offset)|=PIX_MSB; /* point is ABOVE reference */ } } } /* scans 3 and 4 */ #ifdef OPENMP #pragma omp parallel for private(t,s,yxm,q,x,sep,w) #endif for (y=0; y=0) && (NORMU(t[q]-s[q],*(g+s[q]+yxm)) > NORMU(t[q]-x,*(g+x+yxm))) ) q--; if (q<0){ q=0; s[0]=x; } else{ sep=(SQU(x)-SQU(s[q])+SQU(*(g+x+yxm))-SQU(*(g+s[q]+yxm))) / (2*(x-s[q])); w=1+ sep; if (w=0; x--){ if ( *(b+s[q]+yxm) & PIX_MSB ) *(iz+x+yxm)= *(b+s[q]+ (*(g+s[q]+yxm)+y)*m); else *(iz+x+yxm)= *(b+s[q]+ (y-*(g+s[q]+yxm))*m); if( x==t[q] ) q--; } #ifdef OPENMP free(s); free(t); #endif } /* reset input image */ for(i=m*n; i>0; i--) *b++ &= ~PIX_MSB; #ifndef OPENMP free(s); free(t); #endif free_image(img); return(imiz); } #undef BIGVAL #undef GTYPE #undef t_GTYPE #undef GTYPE_MAX #include "uc_undef.h" #include "us_def.h" #ifdef EFEDT_G_IS_UINT32 #define GTYPE UINT32 #define t_GTYPE t_UINT32 #define GTYPE_MAX UINT32_MAX #define BIGVAL (m+n) #else #define GTYPE USHORT #define t_GTYPE t_USHORT #define GTYPE_MAX USHORT_MAX #define BIGVAL (GTYPE_MAX/2) #endif IMAGE *us_iz(IMAGE *im) { IMAGE *img, *imiz; PIX_TYPE *b, *iz; GTYPE *g, bigval; long int *t, *s; int x, y, w, m, n, q, sep; long int i; unsigned long int offset, yxm; m=GetImNx(im); n=GetImNy(im); bigval=BIGVAL; /* make sure the MSB of the input image is always equal to zero (this bit is used for the internal computations) */ b=(PIX_TYPE *)GetImPtr(im); for(i=m*n; i>0; i--) if (*b++ &= PIX_MSB){ (void)sprintf(buf,"IMAGE *us_iz(IMAGE *im): the image values must be <= 32767 (2^15 - 1) !\n"); errputstr(buf); return(NULL); } /* create temporary and output images */ img = create_image(t_GTYPE, GetImNx(im), GetImNy(im), GetImNz(im)); if (img == NULL){ (void)sprintf(buf,"IMAGE *us_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); return(NULL); } imiz = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imiz == NULL){ (void)sprintf(buf,"IMAGE *us_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); free_image(img); return(NULL); } #ifndef OPENMP /* create t and s arrays */ t = (long int *)calloc(sizeof(long int), m); s = (long int *)calloc(sizeof(long int), m); #endif b=(PIX_TYPE *)GetImPtr(im); g=(GTYPE *)GetImPtr(img); iz=(PIX_TYPE *)GetImPtr(imiz); /* scans 1 and 2 */ #ifdef OPENMP #pragma omp parallel for private(x,offset,y) #endif for (x=0; x=0; y--){ /* backward column scan */ offset=x+y*m; if ( *(g+offset+m) < *(g+offset) ){ *(g+offset)=1+*(g+offset+m); *(b+offset)|=PIX_MSB; /* point is ABOVE reference */ } } } /* scans 3 and 4 */ #ifdef OPENMP #pragma omp parallel for private(t,s,yxm,q,x,sep,w) #endif for (y=0; y=0) && (NORMU(t[q]-s[q],*(g+s[q]+yxm)) > NORMU(t[q]-x,*(g+x+yxm))) ) q--; if (q<0){ q=0; s[0]=x; } else{ sep=(SQU(x)-SQU(s[q])+SQU(*(g+x+yxm))-SQU(*(g+s[q]+yxm))) / (2*(x-s[q])); w=1+ sep; if (w=0; x--){ if ( *(b+s[q]+yxm) & PIX_MSB ) *(iz+x+yxm)= *(b+s[q]+ (*(g+s[q]+yxm)+y)*m); else *(iz+x+yxm)= *(b+s[q]+ (y-*(g+s[q]+yxm))*m); if( x==t[q] ) q--; } #ifdef OPENMP free(s); free(t); #endif } /* reset input image */ for(i=m*n; i>0; i--) *b++ &= ~PIX_MSB; #ifndef OPENMP free(s); free(t); #endif free_image(img); return(imiz); } #undef BIGVAL #undef GTYPE #undef t_GTYPE #undef GTYPE_MAX #include "us_undef.h" #include "u32_def.h" #ifdef EFEDT_G_IS_UINT32 #define GTYPE UINT32 #define t_GTYPE t_UINT32 #define GTYPE_MAX UINT32_MAX #define BIGVAL (m+n) #else #define GTYPE USHORT #define t_GTYPE t_USHORT #define GTYPE_MAX USHORT_MAX #define BIGVAL (GTYPE_MAX/2) #endif IMAGE *u32_iz(IMAGE *im) { IMAGE *img, *imiz; PIX_TYPE *b, *iz; GTYPE *g, bigval; long int *t, *s; int x, y, w, m, n, q, sep; long int i; unsigned long int offset, yxm; m=GetImNx(im); n=GetImNy(im); bigval=BIGVAL; /* make sure the MSB of the input image is always equal to zero (this bit is used for the internal computations) */ b=(PIX_TYPE *)GetImPtr(im); for(i=m*n; i>0; i--) if (*b++ >= PIX_MSB){ (void)sprintf(buf,"IMAGE *us_iz(IMAGE *im): the image values must be <= 2147483647 (2^31 - 1) !\n"); errputstr(buf); return(NULL); } /* create temporary and output images */ img = create_image(t_GTYPE, GetImNx(im), GetImNy(im), GetImNz(im)); if (img == NULL){ (void)sprintf(buf,"IMAGE *u32_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); return(NULL); } imiz = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imiz == NULL){ (void)sprintf(buf,"IMAGE *u32_iz(IMAGE *im): not enough memory!\n"); errputstr(buf); free_image(img); return(NULL); } #ifndef OPENMP /* create t and s arrays */ t = (long int *)calloc(sizeof(long int), m); s = (long int *)calloc(sizeof(long int), m); #endif b=(PIX_TYPE *)GetImPtr(im); g=(GTYPE *)GetImPtr(img); iz=(PIX_TYPE *)GetImPtr(imiz); /* scans 1 and 2 */ #ifdef OPENMP #pragma omp parallel for private(x,offset,y) #endif for (x=0; x=0; y--){ /* backward column scan */ offset=x+y*m; if ( *(g+offset+m) < *(g+offset) ){ *(g+offset)=1+*(g+offset+m); *(b+offset)|=PIX_MSB; /* point is ABOVE reference */ } } } /* scans 3 and 4 */ #ifdef OPENMP #pragma omp parallel for private(t,s,yxm,q,x,sep,w) #endif for (y=0; y=0) && (NORMU(t[q]-s[q],*(g+s[q]+yxm)) > NORMU(t[q]-x,*(g+x+yxm))) ) q--; if (q<0){ q=0; s[0]=x; } else{ sep=(SQU(x)-SQU(s[q])+SQU(*(g+x+yxm))-SQU(*(g+s[q]+yxm))) / (2*(x-s[q])); w=1+ sep; if (w=0; x--){ if ( *(b+s[q]+yxm) & PIX_MSB ) *(iz+x+yxm)= *(b+s[q]+ (*(g+s[q]+yxm)+y)*m); else *(iz+x+yxm)= *(b+s[q]+ (y-*(g+s[q]+yxm))*m); if( x==t[q] ) q--; } #ifdef OPENMP free(s); free(t); #endif } /* reset input image */ for(i=m*n; i>0; i--) *b++ &= ~PIX_MSB; #ifndef OPENMP free(s); free(t); #endif free_image(img); return(imiz); } #undef BIGVAL #undef GTYPE #undef t_GTYPE #undef GTYPE_MAX #include "u32_undef.h" IMAGE *iz(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return (uc_iz(im)); break; case t_USHORT: return (us_iz(im)); break; case t_UINT32: return (u32_iz(im)); break; default: (void)sprintf(buf,"iz(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return NULL; } /*@}*/ jeolib-miallib-1.1.6/core/c/epc.c000066400000000000000000000100331467232417700164710ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "miallib.h" /** \addtogroup group_hmtsk * @{ */ #include "uc_def.h" /* epc: extract pixel configurations in a binary image (given by a LUT stored in an image)*/ IMAGE *epc(IMAGE *im, IMAGE *lut) { IMAGE *imout; PIX_TYPE *pcrt, *pend, *plut, *pim, *pout; int code, k, shft[27], *pshft; pshft = &shft[0]; if (GetImDataType(im) != t_UCHAR || GetImDataType(lut) != t_UCHAR || GetImNPix(lut)!=512){ (void)sprintf(buf,"extract_pixel(): invalid pixel type, both inputs must be of t_UCHAR or lut image not of size 512\n"); errputstr(buf); return(NULL); } imout = (IMAGE *)create_image(t_UCHAR, GetImNx(im), GetImNy(im), GetImNz(im)); if (imout==NULL) return(NULL); /* set shift array */ shft[5] = -GetImNx(im) -1; shft[1] = -GetImNx(im); shft[4] = -GetImNx(im) +1; shft[2] = -1; shft[0] = +1; shft[6] = +GetImNx(im) -1; shft[3] = +GetImNx(im); shft[7] = +GetImNx(im) +1; pcrt = (PIX_TYPE *)GetImPtr(im)+GetImNx(im)+1;; pend = (PIX_TYPE *)GetImPtr(im)+GetImNPix(im)-GetImNx(im)-1;; plut = (PIX_TYPE *)GetImPtr(lut); pim = (PIX_TYPE *)GetImPtr(im); pout = (PIX_TYPE *)GetImPtr(imout); /* the lut image must given on/off codes using the following configuration coding scheme: 064 004 032 008 001 002 128 016 256 */ for (; pcrt=*pcrt) code +=acode[k]; } if (plut[code]) pout[pcrt-pim]=1; } return imout; } #include "uc_undef.h" /*@}*/ jeolib-miallib-1.1.6/core/c/erodil.c000066400000000000000000000722741467232417700172170ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif extern void uc_set_shift_and_box_and_weight(unsigned char *im1, UCHAR *im2, int *box, long int x, long int y, long int *shift, UCHAR *weight); typedef struct tms Ttime; /** @defgroup group_erodil Erosions and dilations * Functions dealing with mathematical morphology erosions and dilations. * @{ */ #include "uc_def.h" IMAGE *uc_erode2(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag) /* slower (and using realloc) version whereby a frame is added and then subtracted */ { IMAGE *imout; int box[BOXELEM]; long int *shft, n; PIX_TYPE *p1, *p2, *im1; long int k, x, y, z; long int lstx, lsty, lstz; int nx,ny,nz; /* create shift array */ n = objectpix(imse); if (n==0) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"erode(): not enough memory!\n"); errputstr(buf); return(imout); } nx=GetImNx(imse); ny=GetImNy(imse); nz=GetImNz(imse); if (trflag){ ox=nx-ox-1; oy=ny-oy-1; oz=nz-oz-1; } /* set box values */ if (ox < 0) box[0] = 0; else box[0] = ox; if (ox >= nx) box[1] = 0; else box[1] = nx - 1 - ox; if (oy < 0) box[2] = 0; else box[2] = oy; if (oy >= ny) box[3] = 0; else box[3] = ny - 1 - oy; if (oz < 0) box[4] = 0; else box[4] = oz; if (oz >= nz) box[5] = 0; else box[5] = nz - 1 - oz; generic_addframebox(im, box, PIX_MAX); nx=GetImNx(im); ny=GetImNy(im); nz=GetImNz(im); /* set shifts */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((unsigned char *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); /* here we go */ lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; p2=(PIX_TYPE *)GetImPtr(imout); im1=(PIX_TYPE *)GetImPtr(im); for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ *p2 = *(p1 + shft[0]); for (k = 1; k < n; k++){ if (*p2 > *(p1 + shft[k])) *p2 = *(p1 + shft[k]); } p1++; p2++; } p1 += box[0] + box[1]; } } subframebox(im, box); free((char *) shft); return(imout); } #include "uc_undef.h" #include "uc_def.h" void uc_erode(IMAGE *im, IMAGE *imout, int nx, int ny, int nz, int *box, long int *shft, int n) { PIX_TYPE *im1, *im2, *p1, *p2; IMAGE *im_frame; long int k, x, y, z; long int lstx, lsty, lstz; im1 = (PIX_TYPE *)GetImPtr(im); im2 = (PIX_TYPE *)GetImPtr(imout); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; im_frame = getframebox(im, box); generic_framebox(im, box, PIX_MAX); for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ *p2 = *(p1 + shft[0]); for (k = 1; k < n; k++){ if (*p2 > *(p1 + shft[k])) *p2 = *(p1 + shft[k]); } p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } setframebox(im, im_frame, box); free_image(im_frame); } #include "uc_undef.h" #include "us_def.h" void us_erode(IMAGE *im, IMAGE *imout, int nx, int ny, int nz, int *box, long int *shft, int n) { PIX_TYPE *im1, *im2, *p1, *p2; IMAGE *im_frame; long int k, x, y, z; long int lstx, lsty, lstz; im1 = (PIX_TYPE *)GetImPtr(im); im2 = (PIX_TYPE *)GetImPtr(imout); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; im_frame = getframebox(im, box); us_framebox(im, box, PIX_MAX); for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ *p2 = *(p1 + shft[0]); for (k = 1; k < n; k++){ if (*p2 > *(p1 + shft[k])) *p2 = *(p1 + shft[k]); } p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } setframebox(im, im_frame, box); free_image(im_frame); } #include "us_undef.h" #include "i32_def.h" void i32_erode(IMAGE *im, IMAGE *imout, int nx, int ny, int nz, int *box, long int *shft, int n) { PIX_TYPE *im1, *im2, *p1, *p2; IMAGE *im_frame; long int k, x, y, z; long int lstx, lsty, lstz; im1 = (PIX_TYPE *)GetImPtr(im); im2 = (PIX_TYPE *)GetImPtr(imout); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; im_frame = getframebox(im, box); i32_framebox(im, box, PIX_MAX); for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ *p2 = *(p1 + shft[0]); for (k = 1; k < n; k++){ if (*p2 > *(p1 + shft[k])) *p2 = *(p1 + shft[k]); } p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } setframebox(im, im_frame, box); free_image(im_frame); } #include "i32_undef.h" IMAGE *erode(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag) { IMAGE *imout; int box[BOXELEM]; int n, i, abval; long int *shft; /* check */ if (GetImDataType(imse)!=t_UCHAR){ (void)sprintf(buf,"erode(): imse must be of type UCHAR!\n"); errputstr(buf); return NULL; } /* create shift array */ n = objectpix(imse); if (n==0) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"erode(): not enough memory!\n"); errputstr(buf); return(imout); } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((unsigned char *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (trflag){ /* reflect SE and box values */ for (i=0;i *(p1 + shft[k]) + weight[k]) *p2 = *(p1 + shft[k]) + weight[k]; } p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } } #include "uc_undef.h" IMAGE *volerode(IMAGE *im, IMAGE *imse, IMAGE *imweight, int ox, int oy, int oz) { IMAGE *imout=NULL, *imtmp=NULL; int box[BOXELEM]; int n; long int *shft; UCHAR *ptrf, *weight; /* make sure image of weights is of UCHAR type */ if ((GetImDataType(imweight)!=t_UCHAR) || (GetImDataType(imse)!=t_UCHAR) ){ return NULL; } else /* create shift array */ n = objectpix(imse); if (n==ERROR) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; weight = (UCHAR *)calloc(n, sizeof(UCHAR)); if (weight == NULL){ free(shft); return NULL; } /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ free(shft); free(weight); (void)sprintf(buf,"volerode(): not enough memory!\n"); errputstr(buf); return(imout); } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; ptrf=(UCHAR *)GetImPtr(imtmp); uc_set_shift_and_box_and_weight((unsigned char *)GetImPtr(imse), ptrf, box, \ GetImNx(im), GetImNy(im), shft, weight); if (imtmp!=NULL) free_image(imtmp); switch (GetImDataType(im)){ case t_UCHAR: uc_volerode((UCHAR *)GetImPtr(im), (UCHAR *)GetImPtr(imout), GetImNx(im), GetImNy(im), GetImNz(im), box, shft, weight, n); break; default: (void)sprintf(buf,"volerode(): invalid pixel type\n"); errputstr(buf); free_image(imout); imout=NULL; } free((char *) shft); free((char *) weight); return(imout); } #include "i32_def.h" void i32_voldilate(im1, im2, nx, ny, nz, box, shft, weight, n) PIX_TYPE *im1, *im2; long int nx, ny, nz; int *box; long int *shft, *weight; long int n; { PIX_TYPE *p1, *p2; long int k, x, y, z; long int lstx, lsty, lstz; lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ *p2 = *(p1 + shft[0]) + weight[0]; for (k = 1; k < n; k++){ if (*p2 < *(p1 + shft[k]) + weight[k]) *p2 = *(p1 + shft[k]) + weight[k]; } p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } } #include "i32_undef.h" #include "uc_def.h" ERROR_TYPE uc_erode4(IMAGE *im, int ox, int oy) { PIX_TYPE *pim, *pci, out, *p1, *p2, *p3, *p[3]; PIX_TYPE *pc1, *pc2, *pc3, *pc4, *pc5; int nx=GetImNx(im), ny=GetImNy(im); int i, x, bnx=nx+2; pim=(PIX_TYPE *)GetImPtr(im); pci=pim; p1=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); p2=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); p3=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); for(i=0; i 2) || (oy > 2) ){ (void)sprintf(buf,"erode4(im): ox and oy must be <= 2\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(im)){ case t_UCHAR: return(uc_erode4(im, ox, oy)); break; case t_USHORT: return(us_erode4(im, ox, oy)); break; case t_INT32: return(i32_erode4(im, ox, oy)); break; case t_UINT32: return(u32_erode4(im, ox, oy)); break; case t_FLOAT: return(f_erode4(im, ox, oy)); break; default: (void)sprintf(buf,"erode4(im): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" ERROR_TYPE uc_dilate4(IMAGE *im, int ox, int oy) { PIX_TYPE *pim, *pci, out, *p1, *p2, *p3, *p[3]; PIX_TYPE *pc1, *pc2, *pc3, *pc4, *pc5; int nx=GetImNx(im), ny=GetImNy(im); int i, x, bnx=nx+2; pim=(PIX_TYPE *)GetImPtr(im); pci=pim; p1=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); p2=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); p3=(PIX_TYPE *)calloc(bnx, sizeof(PIX_TYPE)); if (PIX_MIN != 0){ for(i=0; iout) out=pc2[x]; if(pc3[x]>out) out=pc3[x]; if(pc4[x]>out) out=pc4[x]; if(pc5[x]>out) out=pc5[x]; pci[x]=out; } pci+=nx; pc1=p1; p1=p2; p2=p3; p3=pc1; if(iout) out=pc2[x]; if(pc3[x]>out) out=pc3[x]; if(pc4[x]>out) out=pc4[x]; if(pc5[x]>out) out=pc5[x]; pci[x]=out; } pci+=nx; pc1=p1; p1=p2; p2=p3; p3=pc1; if(iout) out=pc2[x]; if(pc3[x]>out) out=pc3[x]; if(pc4[x]>out) out=pc4[x]; if(pc5[x]>out) out=pc5[x]; pci[x]=out; } pci+=nx; pc1=p1; p1=p2; p2=p3; p3=pc1; if(iout) out=pc2[x]; if(pc3[x]>out) out=pc3[x]; if(pc4[x]>out) out=pc4[x]; if(pc5[x]>out) out=pc5[x]; pci[x]=out; } pci+=nx; pc1=p1; p1=p2; p2=p3; p3=pc1; if(iout) out=pc2[x]; if(pc3[x]>out) out=pc3[x]; if(pc4[x]>out) out=pc4[x]; if(pc5[x]>out) out=pc5[x]; pci[x]=out; } pci+=nx; pc1=p1; p1=p2; p2=p3; p3=pc1; if(i 2) || (oy > 2) ){ (void)sprintf(buf,"dilate4(im): ox and oy must be <= 2\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(im)){ case t_UCHAR: return(uc_dilate4(im, ox, oy)); break; case t_USHORT: return(us_dilate4(im, ox, oy)); break; case t_INT32: return(i32_dilate4(im, ox, oy)); break; case t_UINT32: return(u32_dilate4(im, ox, oy)); break; case t_FLOAT: return(f_dilate4(im, ox, oy)); break; default: (void)sprintf(buf,"dilate4(im): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /**@}*/ jeolib-miallib-1.1.6/core/c/f_def.h000066400000000000000000000020761467232417700170020ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for float data types */ #define FLOATING 1 #define SIGNED 1 #define OVFL_TEST 0 #define t_PIX_TYPE t_MIALFLOAT #define PIX_TYPE MIALFLOAT #define PIX_MIN MIALFLOAT_MIN #define PIX_MAX MIALFLOAT_MAX jeolib-miallib-1.1.6/core/c/f_undef.h000066400000000000000000000017761467232417700173530ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for float data types */ #undef FLOATING #undef SIGNED #undef t_PIX_TYPE #undef OVFL_TEST #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX jeolib-miallib-1.1.6/core/c/fah.c000066400000000000000000000104111467232417700164600ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "fah.h" #include "miallib.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif /* ** Create a new circular FIFO queue of size length. */ FIFO *alloc_fifo(long int length) { /* ** author: Pierre Soille ** length: number of elements of the queue */ FIFO *q = (FIFO *)malloc(sizeof(FIFO)); if (q == NULL) return NULL; else{ if ((q->qp = (long int *)calloc(length, sizeof(long int))) == NULL){ (void) sprintf(buf, "alloc_fifo(): NOT ENOUGH MEMORY FOR THE QUEUE\n"); errputstr(buf); return NULL; } else{ q->qps = q->qp; q->qpr = q->qp; q->qplast = q->qp + length; /* BUG ? -1 ... ? */ q->qpl = NULL; q->qcount = 1; q->qlength = length; return q; } } } /* ** Add data in back of the circular FIFO. */ void fifo_add(FIFO *q, long int val) { /* ** author: Pierre Soille ** q: pointer to a queue ** val: value to add in the queue */ *(q->qps++) = val; if (q->qps == q->qpr) fifo_increase(q); if (q->qps == q->qplast){ if (q->qpr == q->qp) fifo_increase(q); else q->qps = q->qp; /* Loop back */ } } /* ** Return data in front of the circular FIFO. */ long int fifo_remove(FIFO *q) { /* ** author: Pierre Soille ** q: pointer to a queue */ if (q->qpr == q->qplast) q->qpr = q->qp; /* Loop back */ if (q->qpr == q->qps) return 0; /* FIFO is empty */ /* Return first element */ return *(q->qpr++); } /* ** Look data in front of the circular FIFO. */ long int fifo_look(FIFO *q) { if (q->qpl == q->qplast) q->qpl = q->qp; /* Loop back */ if (q->qpl == q->qps) return 0; /* End of look */ /* Return first element */ return *(q->qpl++); } /* ** Return TRUE if FIFO is empty. */ long int fifo_empty(FIFO *q) { if (q->qpr == q->qplast) q->qpr = q->qp; /* Loop back */ if (q->qpr == q->qps) return TRUE; /* FIFO is empty */ else return FALSE; /* FIFO is not empty */ } /* ** Increase the size of the FIFO. */ void fifo_increase(FIFO *q) { /* ** author: Pierre Soille ** q: pointer to a queue */ long int qoffset_s, qoffset_r, qoffset_l, qlength, *qptr1, *qptr2; register long int i; qoffset_s = (long int)(q->qps - q->qp); qoffset_r = (long int)(q->qpr - q->qp); qoffset_l = (long int)(q->qplast - q->qp); qlength = (long int)(q->qplast - q->qp + 1 + (q->qplast - q->qp + 1) / q->qcount); if ((q->qp = (long int *)realloc(q->qp, qlength * sizeof(long int))) == NULL){ (void) sprintf(buf,"fifo_increase(): NOT ENOUGH MEMORY !!!\n"); errputstr(buf); exit(0); } q->qlength = qlength; q->qplast = q->qp + qlength; q->qcount++; q->qps = q->qp + qoffset_s; qptr1 = q->qplast; qptr2 = q->qp + qoffset_l; if (qoffset_r != 0){ for (i = qoffset_r; i < qoffset_l; ++i) *(--qptr1) = *(--qptr2); } q->qpr = qptr1; } /* ** Free the memory related to the FIFO queue q. */ void clear_fifo(FIFO *q) { /* ** author: Pierre Soille ** q: pointer to a queue */ if (q->qp != NULL) free((char *)q->qp); if (q != NULL) free((char *)q); } /* ** Free the memory related to the FIFO queue q. */ void fifo_reset(FIFO *q) { /* ** author: Pierre Soille ** q: pointer to a queue */ q->qps = q->qp; q->qpr = q->qp; q->qplast = q->qp + q->qlength; q->qpl = NULL; } jeolib-miallib-1.1.6/core/c/fah.h000066400000000000000000000030121467232417700164640ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ typedef struct { long int *qp; /* Pointer to circular queue */ long int *qps; /* Pointer to storage position */ long int *qpr; /* Pointer to retrieve position */ long int *qplast; /* Pointer to last+1 element */ long int *qpl; /* Pointer to look position */ long int qcount; /* Used to resize the queue */ long int qlength; /* length of the queue */ } FIFO; extern FIFO *alloc_fifo(long int); extern void fifo_add(FIFO *, long int); extern long int fifo_remove(FIFO *); extern long int fifo_look(FIFO *); extern long int fifo_empty(FIFO *); extern void fifo_increase(FIFO *); extern void fifo_reset(FIFO *); extern void clear_fifo(FIFO *); jeolib-miallib-1.1.6/core/c/fifo.c000066400000000000000000000110751467232417700166540ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* fifo data structure */ #include #include #include "fifo.h" #if (defined(XLISP)) extern char buf[]; /* used by sprintf() and stdputstr() */ extern void stdputstr(); /* print a message to the standard output */ extern void errputstr(); /* print a message to the standard error */ #else extern char buf[]; /* used by sprintf() and stdputstr() */ extern void stdputstr(); /* print a message to the standard output */ extern void errputstr(); /* print a message to the standard error */ #endif extern void nrerror(char *); /* GLOUP: the look functions seems a bit dodgy */ /* ** Create a new circular FIFO queue of size length. */ FIFO4 *create_fifo4(long int mod) { FIFO4 *q; q = (FIFO4 *)malloc(sizeof(FIFO4)); if (q != NULL){ if ((q->qp = (long int *)calloc(mod+2, sizeof(long int))) != NULL){ q->qps = q->qp; q->qpr = q->qp; q->qplast = q->qp + mod + 1; q->qpl = q->qp; q->mod = mod+2; } else return NULL; } return q; /* return the pointer to the queue (NULL if not created) */ } /* ** Add data in back of the circular FIFO. */ void fifo4_add(FIFO4 *q, long int data) { *(q->qps++) = data; if (q->qps == q->qpr) fifo4_increase(q); if (q->qps > q->qplast){ if (q->qpr == q->qp) fifo4_increase(q); else q->qps = q->qp; /* Loop back */ } } /* ** Return data in front of the circular FIFO. */ long int fifo4_remove(FIFO4 *q) { if (q->qpr > q->qplast) q->qpr = q->qp; /* Loop back */ if (q->qpr == q->qps) return 0; /* FIFO is empty */ return *(q->qpr++); /* Return first element */ } /* ** Look data in front of the circular FIFO. 2004/03/4: ** BEWARE that fifo4_reset must be called beforehand ** and that no fifo4_remove operations must be performed ** during a cycle of fifo4_look calls. ** Indeed, qpl is not reset when calling fifo4_remove! */ long int fifo4_look(FIFO4 *q) { if (q->qpl > q->qplast) q->qpl = q->qp; /* Loop back */ if (q->qpl == q->qps) return 0; /* End of look */ return *(q->qpl++); /* Return first element */ } /* ** Reset the look position to the first element to retrieve from the queue. ** 2001-11-08 */ void fifo4_lookreset(FIFO4 *q) { q->qpl = q->qpr; } /* ** Flush the queue */ void fifo4_flush(FIFO4 *q) { q->qps = q->qp; q->qpr = q->qp; q->qpl = q->qp; } /* ** Return 1 if FIFO is empty. */ long int fifo4_empty(FIFO4 *q) { if (q->qpr > q->qplast) q->qpr = q->qp; /* Loop back */ if (q->qpr == q->qps) return 1; /* FIFO is empty */ else return 0; /* FIFO is not empty */ } /* ** Increase the size of the FIFO. */ void fifo4_increase(FIFO4 *q) { long int qoffset_s, qoffset_r, qoffset_last; /* , qoffset_l */ long int nelem, *qptr1, *qptr2; long int i; qoffset_s = (long int)(q->qps - q->qp); qoffset_r = (long int)(q->qpr - q->qp); /* qoffset_l = (long int)(q->qpl - q->qp); */ qoffset_last = (long int)(q->qplast - q->qp); nelem = (long int)(q->qplast - q->qp) + q->mod + 1; if ((q->qp = (long int *)realloc(q->qp, nelem*sizeof(long int))) == NULL) nrerror("fifo4_increase(): not enough memory"); q->qplast = q->qp + nelem - 1; q->qps = q->qp + qoffset_s; qptr1 = q->qplast; qptr2 = q->qp + qoffset_last; if (qoffset_r != 0){ for (i = qoffset_r; i <= qoffset_last; i++, qptr1--, qptr2--) *qptr1 = *qptr2; q->qpr = (qptr1+1); } else q->qpr = q->qp; /* on 2001-11-13 if (qoffset_l <= qoffset_s) q->qpl = q->qp + qoffset_l; else q->qpl = q->qp + qoffset_l + q->mod; */ q->qpl = q->qpr; } /* ** Free the memory related to the FIFO queue q. */ void free_fifo4(FIFO4 *q) { if (q->qp != NULL) free((char *)q->qp); if (q != NULL) free((char *)q); } jeolib-miallib-1.1.6/core/c/fifo.h000066400000000000000000000031251467232417700166560ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* ** FIFO type definition */ typedef struct { long int *qp; /* Pointer to circular queue */ long int *qps; /* Pointer to storage position */ long int *qpr; /* Pointer to retrieve position */ long int *qplast; /* Pointer to last+1 element */ long int *qpl; /* Pointer to look position */ long int mod; /* Modulation factor */ } FIFO4; #define FICT_PIX 1 extern FIFO4 *create_fifo4(long int); extern void fifo4_add(FIFO4 *, long int); extern long int fifo4_remove(FIFO4 *); extern long int fifo4_look(FIFO4 *); extern void fifo4_lookreset(FIFO4 *); extern long int fifo4_empty(FIFO4 *); extern void fifo4_increase(FIFO4 *); extern void free_fifo4(FIFO4 *); extern void fifo4_flush(FIFO4 *); jeolib-miallib-1.1.6/core/c/fillocarve.c000066400000000000000000001321141467232417700200550ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2002-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Optimal removal of spurious pits in digital elevation models \cite soille2004wrr and \cite soille2004prl * @author Pierre Soille */ #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" #include "pqueue.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif /** \addtogroup group_dem * @{ */ #include "us_def.h" #define LABEL_TYPE unsigned short #define LABEL_MAX 0x7FFF /* 16383 */ /* was 0x7FFF */ #define LABEL_MSB 0x8000 #define FLOODED 0x80 #define REACHED 0x40 #define FLRE 0x0F /* FLOODED|REACHED */ IMAGE *us_fillocarve_energy(unsigned short *iml, unsigned short *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE 20-11-2002 (1st) ** iml: pointer to an image of labels with LABEL_MAX valued border (relevant minima) ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ /* char fname[50]; */ int pcount=0; IMAGE im[2]; int box[6]; int casea=0, caseae=0, caseb=0, casebe=0, casec=0, casece=0, cased=0, casede=0; /* 2003-11-10 */ int *eeb; /* 2003-11-12 for energy of embedded pit */ int *ec, *ef, *af, dyn, iori=0; int h, priocrt=0, ah, level, emin; struct pqueue *heap; PQDATUM apqd[1]; struct node *pqd; UCHAR *apdir, *apdirk; int flag=1, flage=0; long int index; long int k, ofs, ofsk, ofsi=0; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; long int i, shftk, npix; IMAGE *imdir; UCHAR *pdir; FIFO4 *aq; LABEL_TYPE *p1, *p2; PIX_TYPE minval; long int ak, bofs, crtlevel; heap = (struct pqueue *)pqinit(NULL, 100); /* heap (priority queue) */ if (heap == NULL) return NULL; npix = (long int)nx*ny*nz; maxfl++; im[0].p_im = (char *)iml; im[0].DataType = 5; im[0].nx = nx; im[0].ny = ny; im[0].nz = nz; im[0].NByte = (mia_size_t)nx*ny*nz*2; im[0].vol = 0; im[0].lut = NULL; im[1].p_im = (char *)imr; im[1].DataType = 5; im[1].nx = nx; im[1].ny = ny; im[1].nz = nz; im[1].NByte = (mia_size_t)nx*ny*nz*2; im[1].vol = 0; im[1].lut = NULL; BOX_2D; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("fillocarve(): not enough memory for the FAH\n"); return NULL; } /* create maxfl queues */ for (i=0; i1)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; icrtlevel){ /* perhaps should simply follow steepest slope path */ // printf("We go down\n"); if (flag){ iori=i; ofsi=ofs; /* printf("iori=%d\n", iori); */ flag=0; } i=crtlevel; pq=fah[crtlevel]; } /* else if (iprio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* pqd->prio = PIX_RANGE-( *(imr+index+shft[ak]) - minval ); */ /* pqd->val = val; not used */ pqd->offset= (long int)(index+shft[ak]); pqinsert(heap, pqd); *apdirk |= REACHED; } } } free_fifo4(aq); ef[1]=af[0]; bofs=ofs; /* calculate ec[0] */ while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval) ec[0]+= *(imr+bofs)-(minval); /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } emin=ec[0]; /* look for procedure with lowest energy */ for (h=1,ah=1; hminval){ /* backtrack */ if (*(imr+bofs)>minval+h) ec[h]+= *(imr+bofs)-(minval+h); /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } /* check whether total energy increases, and break if so */ ef[h]=ef[h-1]+af[h-1]+eeb[h-1]; if (ec[h]+ef[h] > emin){ /* minimum energy reached */ if ( ec[0]==emin ) if (flage == 0) casea++; /* pure plain carving */ else{ caseae++; /* embedded carving (should not occur) */ // printf("h=%d ec[0]=%d\t ec[1]+ef[1]=%d\n", h, ec[0], ec[1]+ef[1]); } else if (flage == 0) caseb++; /* pure hybrid approach */ else casebe++; /* embedded hybrid */ break; } emin=ec[h]+ef[h]; /* compute energy of fillhole */ if ( pqpeek(heap, apqd) == NULL ) priocrt=h; while ( pqpeek(heap, apqd) != NULL ){ /* it may be empty !!! */ priocrt=PIX_RANGE-(*apqd)->prio; /* printf("h=%d\t priocrt=%d\n", h, priocrt); */ if (priocrt > h) /* no pixel to flood at the current level */ break; /* while loop */ af[h]+= 1; /* only for area part of mewly flooded pixel (downward for embedded) */ if (priocrt < h){ /* embedded pits */ eeb[h]+=minval+h-*(imr+ (int)(*apqd)->offset); flage=1; } /* printf("minval=%d\t h=%d\t af[h]=%d\t eeb[%d]=%d\n", minval, h, minval+h+1-*(imr+ (int)(*apqd)->offset ), h, eeb[h]); */ pqremove(heap, apqd); apdir=pdir+(*apqd)->offset; free((char*) *apqd); *apdir|=FLOODED; /* printf("af[%d]=%d\n",h,af[h]); */ for (ak=0; ak < nshft; ak++){ apdirk=apdir+shft[ak]; if ( (*apdirk<8) && (*(iml+(apdirk-pdir))!=LABEL_MAX) && (*(imr+ (int) (apdirk-pdir))) < iori){ /* not yet flooded */ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* printf("*(imr+ (int) (apdirk-pdir))=%d\t", *(imr+ (int) (apdirk-pdir))); */ /* printf("offset=%d\t", apdirk-pdir); */ /* printf("prio=%d\n", (*(imr+ (int) (apdirk-pdir))-minval)); */ /* pqd->val = val; not used */ pqd->offset= (long int)(apdirk-pdir); pqinsert(heap, pqd); *apdirk|=REACHED; } } } af[h]+=af[h-1]; /* printf("iori=%d\t minval=%d\t dyn=%d\t priocrt=%d\t h=%d\n", iori, minval, dyn, priocrt, h); */ /* if (ofsk==35400){ printf("non-positive dynamyic, ofsk=%ld!!!\n", ofsk); dumpxyz(&im[0],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); dumpxyz(&im[1],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); } */ } /* for (h=0; hoffset)&=FLRE; /* reset */ free((char*) *apqd); } /* dumpxyz(&im[1],10,0,0,20,20); */ /* carve from minval+ah */ bofs=ofs; while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval+ah){/* carve */ *(imr+bofs)=minval+ah; } bofs-=shft[pdir[bofs]&FLRE]; } /* printf("before fill by ah\n"); */ /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ /* fill by ah and reset all flooded minima (holds for embedded ones) */ level=ah+minval; aq = create_fifo4(10); fifo4_add(aq, (long int)(ofsk)); *(imr+ofsk)=level; *(iml+ofsk)=0; while ((index = fifo4_remove(aq))){ for (ak=0; ak < nshft; ak++){ p2 = iml + index + shft[ak]; if (*p2 == 1){ /* reset minimum */ *p2=0; *(imr+index+shft[ak])=level; fifo4_add(aq, (long int)(index+shft[ak])); } else if (*(imr+index+shft[ak]) 8){ /* also resets FLOODED/REACHED PIXELS */ *(pdir+index+shft[ak])&=FLRE; fifo4_add(aq, (long int)(index+shft[ak])); } } } free_fifo4(aq); /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ } /* if (*(iml+ofsk)==1)irrelevant minima reached */ *(iml+ofsk)=*(iml+ofs); } else /* if (*imr+ofsk) 1)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; icrtlevel){ /* perhaps should simply follow steepest slope path */ /* printf("We go down\n"); */ if (flag){ iori=i; ofsi=ofs; /* printf("iori=%d\n", iori); */ flag=0; } i=crtlevel; pq=fah[crtlevel]; } /* else if (iprio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* pqd->prio = PIX_RANGE-( *(imr+index+shft[ak]) - minval ); */ /* pqd->val = val; not used */ pqd->offset= (long int)(index+shft[ak]); pqinsert(heap, pqd); *apdirk |= REACHED; } } } free_fifo4(aq); ef[1]=af[0]; bofs=ofs; /* calculate ec[0] */ while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval) ec[0]+= *(imr+bofs)-(minval); /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } emin=ec[0]; /* look for procedure with lowest energy */ for (h=1,ah=1; hminval){ /* backtrack */ if (*(imr+bofs)>minval+h) ec[h]+= *(imr+bofs)-(minval+h); /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } /* check whether total energy increases, and break if so */ ef[h]=ef[h-1]+af[h-1]+eeb[h-1]; if (ec[h]+ef[h] > emin){ /* minimum energy reached */ if ( ec[0]==emin ) if (flage == 0) casea++; /* pure plain carving */ else{ caseae++; /* embedded carving (should not occur) */ printf("ec[0]=%d\t ec[1]=%d\n", ec[0], ec[1]+ef[1]); } else if (flage == 0) caseb++; /* pure hybrid approach */ else casebe++; /* embedded hybrid */ break; } emin=ec[h]+ef[h]; /* compute energy of fillhole */ if ( pqpeek(heap, apqd) == NULL ) priocrt=h; while ( pqpeek(heap, apqd) != NULL ){ /* it may be empty !!! */ priocrt=PIX_RANGE-(*apqd)->prio; /* printf("h=%d\t priocrt=%d\n", h, priocrt); */ if (priocrt > h) /* no pixel to flood at the current level */ break; /* while loop */ af[h]+= 1; /* only for area part of mewly flooded pixel (downward for embedded) */ if (priocrt < h){ /* embedded pits */ eeb[h]+=minval+h-*(imr+ (int)(*apqd)->offset); flage=1; } /* printf("minval=%d\t h=%d\t af[h]=%d\t eeb[%d]=%d\n", minval, h, minval+h+1-*(imr+ (int)(*apqd)->offset ), h, eeb[h]); */ pqremove(heap, apqd); apdir=pdir+(*apqd)->offset; free((char*) *apqd); *apdir|=FLOODED; /* printf("af[%d]=%d\n",h,af[h]); */ for (ak=0; ak < nshft; ak++){ apdirk=apdir+shft[ak]; if ( (*apdirk<8) && (*(iml+(apdirk-pdir))!=LABEL_MAX) && (*(imr+ (int) (apdirk-pdir))) < iori){ /* not yet flooded */ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* printf("*(imr+ (int) (apdirk-pdir))=%d\t", *(imr+ (int) (apdirk-pdir))); */ /* printf("offset=%d\t", apdirk-pdir); */ /* printf("prio=%d\n", (*(imr+ (int) (apdirk-pdir))-minval)); */ /* pqd->val = val; not used */ pqd->offset= (long int)(apdirk-pdir); pqinsert(heap, pqd); *apdirk|=REACHED; } } } af[h]+=af[h-1]; /* printf("iori=%d\t minval=%d\t dyn=%d\t priocrt=%d\t h=%d\n", iori, minval, dyn, priocrt, h); */ /* if (ofsk==35400){ printf("non-positive dynamyic, ofsk=%ld!!!\n", ofsk); dumpxyz(&im[0],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); dumpxyz(&im[1],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); } */ } /* for (h=0; hoffset)&=FLRE; /* reset */ free((char*) *apqd); } /* dumpxyz(&im[1],10,0,0,20,20); */ /* carve from minval+ah */ bofs=ofs; while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval+ah){/* carve */ *(imr+bofs)=minval+ah; } bofs-=shft[pdir[bofs]&FLRE]; } /* printf("before fill by ah\n"); */ /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ /* fill by ah and reset all flooded minima (holds for embedded ones) */ level=ah+minval; aq = create_fifo4(10); fifo4_add(aq, (long int)(ofsk)); *(imr+ofsk)=level; *(iml+ofsk)=0; while ((index = fifo4_remove(aq))){ for (ak=0; ak < nshft; ak++){ p2 = iml + index + shft[ak]; if (*p2 == 1){ /* reset minimum */ *p2=0; *(imr+index+shft[ak])=level; fifo4_add(aq, (long int)(index+shft[ak])); } else if (*(imr+index+shft[ak]) 8){ /* also resets FLOODED/REACHED PIXELS */ *(pdir+index+shft[ak])&=FLRE; fifo4_add(aq, (long int)(index+shft[ak])); } } } free_fifo4(aq); /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ } /* if (*(iml+ofsk)==1)irrelevant minima reached */ *(iml+ofsk)=*(iml+ofs); } else /* if (*imr+ofsk) 1)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; icrtlevel){ /* perhaps should simply follow steepest slope path */ /* printf("We go down\n"); */ if (flag){ iori=i; ofsi=ofs; /* printf("iori=%d\n", iori); */ flag=0; } i=crtlevel; pq=fah[crtlevel]; } /* else if (iprio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* pqd->prio = PIX_RANGE-( *(imr+index+shft[ak]) - minval ); */ /* pqd->val = val; not used */ pqd->offset= (long int)(index+shft[ak]); pqinsert(heap, pqd); *apdirk |= REACHED; } } } free_fifo4(aq); ef[1]=af[0]; bofs=ofs; /* calculate ec[0] */ while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval) ec[0]+= 1; /* *(imr+bofs)-(minval); */ /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } emin=ec[0]; hmin=0; /* look for procedure with lowest energy */ for (h=1,ah=1; hminval){ /* backtrack */ if (*(imr+bofs)>minval+h) ec[h]+= 1; /* *(imr+bofs)-(minval+h); */ /* PSH missing parenthesis */ bofs-=shft[pdir[bofs]&FLRE]; } /* check whether total energy decreases*/ ef[h]=af[h-1]; /* ef[h]=ef[h-1]+af[h-1]+eeb[h-1]; */ if (ec[h]+ef[h] <= emin){ emin=ec[h]+ef[h]; hmin=h; } /* compute energy of fillhole */ if ( pqpeek(heap, apqd) == NULL ) priocrt=h; while ( pqpeek(heap, apqd) != NULL ){ /* it may be empty !!! */ priocrt=PIX_RANGE-(*apqd)->prio; /* printf("h=%d\t priocrt=%d\n", h, priocrt); */ if (priocrt > h) /* no pixel to flood at the current level */ break; /* while loop */ af[h]+= 1; /* only for area part of mewly flooded pixel (downward for embedded) */ /* printf("minval=%d\t h=%d\t af[h]=%d\t eeb[%d]=%d\n", minval, h, minval+h+1-*(imr+ (int)(*apqd)->offset ), h, eeb[h]); */ pqremove(heap, apqd); apdir=pdir+(*apqd)->offset; free((char*) *apqd); *apdir|=FLOODED; /* printf("af[%d]=%d\n",h,af[h]); */ for (ak=0; ak < nshft; ak++){ apdirk=apdir+shft[ak]; if ( (*apdirk<8) && (*(iml+(apdirk-pdir))!=LABEL_MAX) && (*(imr+ (int) (apdirk-pdir))) < iori){ /* not yet flooded */ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = PIX_RANGE-(*(imr+ (int) (apdirk-pdir))-minval); /* printf("*(imr+ (int) (apdirk-pdir))=%d\t", *(imr+ (int) (apdirk-pdir))); */ /* printf("offset=%d\t", apdirk-pdir); */ /* printf("prio=%d\n", (*(imr+ (int) (apdirk-pdir))-minval)); */ /* pqd->val = val; not used */ pqd->offset= (long int)(apdirk-pdir); pqinsert(heap, pqd); *apdirk|=REACHED; } } } af[h]+=af[h-1]; /* printf("iori=%d\t minval=%d\t dyn=%d\t priocrt=%d\t h=%d\n", iori, minval, dyn, priocrt, h); */ /* if (ofsk==35400){ printf("non-positive dynamyic, ofsk=%ld!!!\n", ofsk); dumpxyz(&im[0],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); dumpxyz(&im[1],ofsk-(int)(ofsk/nx)*nx,(int)(ofsk/nx),0,10,10); } */ } /* for (h=0; hoffset)&=FLRE; /* reset */ free((char*) *apqd); } /* dumpxyz(&im[1],10,0,0,20,20); */ /* carve from minval+ah */ bofs=ofs; while (*(imr+bofs)>minval){ /* backtrack */ if (*(imr+bofs)>minval+ah){/* carve */ *(imr+bofs)=minval+ah; } bofs-=shft[pdir[bofs]&FLRE]; } /* printf("before fill by ah\n"); */ /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ /* fill by ah and reset all flooded minima (holds for embedded ones) */ level=ah+minval; aq = create_fifo4(10); fifo4_add(aq, (long int)(ofsk)); *(imr+ofsk)=level; *(iml+ofsk)=0; while ((index = fifo4_remove(aq))){ for (ak=0; ak < nshft; ak++){ p2 = iml + index + shft[ak]; if (*p2 == 1){ /* reset minimum */ *p2=0; *(imr+index+shft[ak])=level; fifo4_add(aq, (long int)(index+shft[ak])); } else if (*(imr+index+shft[ak]) 8){ /* also resets FLOODED/REACHED PIXELS */ *(pdir+index+shft[ak])&=FLRE; fifo4_add(aq, (long int)(index+shft[ak])); } } } free_fifo4(aq); /* dumpxyz(&im[0],10,0,0,20,20); */ /* dumpxyz(&im[1],10,0,0,20,20); */ } /* if (*(iml+ofsk)==1)irrelevant minima reached */ *(iml+ofsk)=*(iml+ofs); } else /* if (*imr+ofsk) energy, area otherwise ** ** WARNING: irrelevant minima must have all an intensity greater than that of the lowest minimum! */ long int shft[27]; int box[6]={1,1,1,1,0,0}; set_seq_shift(GetImNx(iml), GetImNy(iml), GetImNz(iml), graph, shft); /* here we go */ switch (GetImDataType(imr)){ case t_USHORT: switch (GetImDataType(iml)){ case t_USHORT: us_framebox(imr,box,0); us_framebox(iml,box,USHORT_MAX); if (flag==0) return(us_fillocarve_energy((unsigned short *)(GetImPtr(iml)),(unsigned short*)(GetImPtr(imr)), GetImNx(iml), GetImNy(iml), GetImNz(iml), shft, graph, maxfl)); else return(us_fillocarve_area((unsigned short *)(GetImPtr(iml)),(unsigned short*)(GetImPtr(imr)), GetImNx(iml), GetImNy(iml), GetImNz(iml), shft, graph, maxfl)); break; default: (void)sprintf(buf, "ERROR in fillocarve(): \ invalid ImDataType for LABEL image\n"); errputstr(buf); return(NULL); } case t_UINT32: switch (GetImDataType(iml)){ case t_USHORT: if (flag==1){ (void)sprintf(buf, "ERROR in fillocarve(): \ invalid ImDataType for grey level image\n"); errputstr(buf); return(NULL); } u32_framebox(imr,box,0); us_framebox(iml,box,USHORT_MAX); return(u32_fillocarve_energy((unsigned short *)(GetImPtr(iml)),(UINT32 *)(GetImPtr(imr)), GetImNx(iml), GetImNy(iml), GetImNz(iml), shft, graph, maxfl)); break; default: (void)sprintf(buf, "ERROR in fillocarve(): \ invalid ImDataType for LABEL image\n"); errputstr(buf); return(NULL); } default: (void)sprintf(buf, "ERROR in fillocarve(): \ invalid ImDataType for grey level image\n"); errputstr(buf); return(NULL); } } /*@}*/ jeolib-miallib-1.1.6/core/c/flatdir.c000066400000000000000000000755241467232417700173670ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Flow directions on plateaus from \cite soille-gratin94 * @author Pierre Soille */ #include #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" #include "pqueue.h" /** \addtogroup group_dem * @{ */ #include "us_def.h" #define FLAT_TYPE USHORT #define PR_MAX 255 #define FLAT_MAX 65535 /* 32767 */ #define FLAT_MAXM1 65534 /* 32766 */ #define FLAT_VAL 65533 /* 32765 */ #define FLAT_DB 65532 /* 32764 */ #define REF_PIX_MSB 0x8000 /* 32768 */ ERROR_TYPE us_FlatIGeodAFAB(IMAGE *flat, IMAGE *im, int graph) { long int i, j, k, t, nx, ny, nz, shft[27]; FIFO4 *q, *qflat, *qdst, *qdb, *qdball; FIFO **fifo, **fifot, *pf; FLAT_TYPE *p, *ptr, *pflat, *pflat0, dcrt, *pm, *pr, *p_k, pr_max; PIX_TYPE *pim, *pim0, flatval; if (szgeocompat(im, flat) != NO_ERROR){ (void) sprintf(buf, "FlatIGeodAFAB(): input images must be of same type\n"); errputstr(buf); return ERROR; } pim=(PIX_TYPE *)GetImPtr(im); pim0=(PIX_TYPE *)GetImPtr(im); pflat=(FLAT_TYPE *)GetImPtr(flat); pflat0=(FLAT_TYPE *)GetImPtr(flat); /* used for computing offsets */ nx =GetImNx(im); ny =GetImNy(im); nz =GetImNz(im); /* set shift array */ set_seq_shift(nx, ny, nz, graph, shft); q = create_fifo4(nx+ny+nz); /* use for geodesic distance computations */ if (q == NULL) return ERROR; qflat = create_fifo4(nx+ny+nz); /* will hold all pixels of flat region */ if (qflat == NULL) return ERROR; qdst = create_fifo4(50); /* used for computing distance transform */ if (qdst == NULL) return ERROR; qdb = create_fifo4(10); /* will hold descending borders of flat region (one at a time) */ if (qdb == NULL) return ERROR; qdball = create_fifo4(nx+ny); /* will hold descending borders of all flat regions */ if (qdball == NULL) return ERROR; #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif for (j=nx*ny*nz; j > 0; j--, pflat++, pim++){ if (*pflat == FLAT_VAL){ /* unprocessed flat region */ *pflat=FLAT_MAX; flatval=*pim; fifo4_add(q, (long int)(pflat)); fifo4_add(qflat, (long int)(pflat)); while (fifo4_empty(q) == 0){ /* fill in flat region and initialize queues */ ptr = (FLAT_TYPE *)fifo4_remove(q); for (k = 0; k < graph; k++){ p = ptr + shft[k]; if (*p == FLAT_VAL){ *p=FLAT_MAX; fifo4_add(q, (long int)p); fifo4_add(qflat, (long int)p); } else if (*(pim0+(p-pflat0))>flatval){ /* external ascending border */ *p=FLAT_MAXM1; fifo4_add(qdst, (long int)p); } else if ((*(pim0+(p-pflat0))==flatval) && (*p==0)){ /* internal descending border */ *p=FLAT_DB; fifo4_add(qdb, (long int)p); fifo4_add(qdball, (long int)p); } } } #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* compute geodesic distances */ dcrt = 0; while (fifo4_empty(qdst) == 0){ fifo4_add(qdst, 1L); while ((pm = (FLAT_TYPE *)fifo4_remove(qdst)) != (FLAT_TYPE *)1L){ *pm = dcrt; for (k=0; k < graph; ++k){ if (*(pm + shft[k]) == FLAT_MAX){ *(pm + shft[k]) = FLAT_MAXM1; fifo4_add(qdst, (long int)(pm + shft[k])); } } } dcrt++; } dcrt++; if (dcrt==1) /* we want to start at 2 */ dcrt=2; #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); /* printf("dcrt=%d\n", dcrt); */ #endif /* invert geodesic distances in flat region */ if (dcrt==2){ /* flat top */ while (fifo4_empty(qflat) == 0){ pm = (FLAT_TYPE *)fifo4_remove(qflat); *pm = 2; } } else{ /* intermediate plateau */ while (fifo4_empty(qflat) == 0){ pm = (FLAT_TYPE *)fifo4_remove(qflat); *pm = dcrt-*pm; } } #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* compute geodesic time function from descending border */ /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return ERROR; } pr_max = PR_MAX; /* initialize the FAH */ while (fifo4_empty(qdb) == 0){ pr = (FLAT_TYPE *)fifo4_remove(qdb); *pr=0; for (k = 0; k < graph; ++k){ p_k=pr + shft[k]; if (*p_k && (*p_k<=dcrt)){ if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return -9; } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } } #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (FLAT_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shft[k]; if (*p_k & REF_PIX_MSB || (*p_k==0)) continue; *p_k += t; if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return ERROR; } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif } } for (j=nx*ny*nz; j > 0; j--, pflat0++) if (*pflat0) *pflat0 ^= REF_PIX_MSB; while (fifo4_empty(qdball) == 0){ /* set to 1 all descending boders */ pm = (FLAT_TYPE *)fifo4_remove(qdball); *pm = 1; } #ifdef XLDEBUG dumpxyz(flat, 0, 0, 0, 44, 44); #endif free_fifo4(q); free_fifo4(qflat); free_fifo4(qdst); free_fifo4(qdb); free_fifo4(qdball); return NO_ERROR; } #undef FLAT_TYPE #undef PR_MAX #undef FLAT_VAL #undef FLAT_MAX #undef FLAT_MAXM1 #undef REF_PIX_MSB #undef FLAT_DB #include "us_undef.h" ERROR_TYPE FlatIGeodAFAB(IMAGE *flat, IMAGE *im, int graph) { /* Compute geodesic distance away from ascending borders on all flat regions, then the geodesic time funtion from descending borders. The flat image must be of type USHORT with pixels without drainage set to 65533 (FLAT_VAL) First: 06-11-2001 */ if (GetImDataType(flat) != t_USHORT){ (void) sprintf(buf, "FlatIGeodAFAB(): the image of flat areas must be of type USHORT (with flat regions set to 65533\n"); errputstr(buf); return ERROR; } switch (GetImDataType(im)){ case t_USHORT: us_FlatIGeodAFAB(flat, im, graph); break; default: (void)sprintf(buf, "ERROR in FlatIGeodAFAB(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "us_def.h" #define FLAT_TYPE USHORT #define PR_MAX 255 #define FLAT_MAX 65535 /* 32767 */ #define FLAT_MAXM1 65534 /* 32766 */ #define FLAT_VAL 65533 /* 32765 */ #define FLAT_DB 65532 /* 32764 */ #define REF_PIX_MSB 0x8000 /* 32768 */ IMAGE *us_FlatDir(IMAGE *flat, IMAGE *im, int graph) { long int i, j, k, t, nx, ny, nz, shft[27]; FIFO4 *q, *qflat, *qdst, *qdb, *qdball, *qab; FIFO **fifo, **fifot, *pf; IMAGE *imdir; FLAT_TYPE *p, *ptr, *pflat, *pflat0, dcrt, *pm, *pr, *p_k, pr_max, vngb, lowest; PIX_TYPE *pim, *pim0, flatval; UCHAR *pdir0, dir; int stmp, delta, slope; /* slope holds twice the square of actual slope */ long int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; #ifdef XLDEBUG int x=2113, y=1131; int dx=10, dy=10; #endif if (szgeocompat(im, flat) != NO_ERROR){ (void) sprintf(buf, "us_FlatDir(): input images must be of same type\n"); errputstr(buf); return NULL; } nx =GetImNx(im); ny =GetImNy(im); nz =GetImNz(im); shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; imdir = (IMAGE *)create_image(t_UCHAR, nx, ny, nz); if (imdir == NULL){ (void)sprintf(buf,"us_FlatDir(): not enough memory!\n"); errputstr(buf); return NULL; } pim=(PIX_TYPE *)GetImPtr(im); pim0=(PIX_TYPE *)GetImPtr(im); pflat=(FLAT_TYPE *)GetImPtr(flat); pflat0=(FLAT_TYPE *)GetImPtr(flat); /* used for computing offsets */ pdir0 = (UCHAR *)GetImPtr(imdir); /* set shift array */ set_seq_shift(nx, ny, nz, graph, shft); q = create_fifo4(500); /* use for geodesic distance computations */ if (q == NULL) return NULL; qflat = create_fifo4(500); /* will hold all pixels of flat region */ if (qflat == NULL) return NULL; qdst = create_fifo4(50); /* used for computing distance transform */ if (qdst == NULL) return NULL; qdb = create_fifo4(10); /* will hold descending borders of flat region (one at a time) */ if (qdb == NULL) return NULL; qdball = create_fifo4(100); /* will hold descending borders of all flat regions */ if (qdball == NULL) return NULL; qab = create_fifo4(10); /* will hold ascending borders of flat region (one at a time) */ if (qab == NULL) return NULL; #ifdef XLDEBUG dumpxyz(flat, x, y, 0, dx, dy); #endif for (j=nx*ny*nz; j > 0; j--, pflat++, pim++){ if (*pflat == FLAT_VAL){ /* unprocessed flat region */ *pflat=FLAT_MAX; flatval=*pim; fifo4_add(q, (long int)(pflat)); fifo4_add(qflat, (long int)(pflat)); while (fifo4_empty(q) == 0){ /* fill in flat region and initialize queues */ ptr = (FLAT_TYPE *)fifo4_remove(q); for (k = 0; k < graph; k++){ p = ptr + shft[k]; if (*p == FLAT_VAL){ *p=FLAT_MAX; fifo4_add(q, (long int)p); fifo4_add(qflat, (long int)p); } else if (*(pim0+(p-pflat0))>flatval && (*p==0)){ /* external ascending border */ *p=FLAT_MAXM1; fifo4_add(qdst, (long int)p); fifo4_add(qab, (long int)p); } else if ((*(pim0+(p-pflat0))==flatval) && (*p==0)){ /* internal descending border */ *p=FLAT_DB; fifo4_add(qdb, (long int)p); fifo4_add(qdball, (long int)p); } } } #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif /* compute geodesic distances */ dcrt = 0; while (fifo4_empty(qdst) == 0){ fifo4_add(qdst, 1L); while ((pm = (FLAT_TYPE *)fifo4_remove(qdst)) != (FLAT_TYPE *)1L){ *pm = dcrt; for (k=0; k < graph; ++k){ if (*(pm + shft[k]) == FLAT_MAX){ *(pm + shft[k]) = FLAT_MAXM1; fifo4_add(qdst, (long int)(pm + shft[k])); } } } dcrt++; } if (dcrt==0) dcrt=1; #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); /* printf("dcrt=%d\n", dcrt); */ #endif /* invert geodesic distances in flat region */ fifo4_lookreset(qflat); if (dcrt==1){ /* flat top */ while ((pm=(FLAT_TYPE *)fifo4_look(qflat)) != NULL){ *pm = 1; } } else{ /* intermediate plateau */ while ((pm=(FLAT_TYPE *)fifo4_look(qflat)) != NULL){ *pm = dcrt-*pm; } } #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* compute geodesic time function from descending border */ /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return NULL; } pr_max = PR_MAX; /* initialize the FAH */ while (fifo4_empty(qdb) == 0){ pr = (FLAT_TYPE *)fifo4_remove(qdb); *pr=0; for (k = 0; k < graph; ++k){ p_k=pr + shft[k]; if (*p_k && (*p_k<=dcrt)){ if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return (NULL); } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } } #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (FLAT_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shft[k]; if (*p_k & REF_PIX_MSB || (*p_k==0)) continue; *p_k += t; if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("us_FlatIGeodAFAB(): not enough memory for the FAH\n"); return (NULL); } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* compute drainage directions on created relief */ fifo4_lookreset(qdball); while ( (pm=(FLAT_TYPE *)fifo4_look(qdball)) != NULL) /* reset to 1 all descending borders */ *pm = 0; fifo4_lookreset(qab); while ( (pm=(FLAT_TYPE *)fifo4_look(qab)) != NULL) /* reset to FLAT_MAX all ascending borders */ *pm = FLAT_MAX; fifo4_lookreset(qflat); while ( (pm=(FLAT_TYPE *)fifo4_look(qflat)) != NULL) /* set all flat pixels to their distance value */ *pm ^= REF_PIX_MSB ; #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif fifo4_lookreset(qflat); while ( (pm=(FLAT_TYPE *)fifo4_look(qflat)) != NULL){ /* compute drainage direction */ lowest=*pm; dir=0; /* no lower neighbour */ slope=0; /* no slope to lower neighbour */ /* process 4-neighbours first */ if (*(pm+shft1)slope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pm+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pm+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pm+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *(pdir0+(pm-pflat0))=dir; } #ifdef XLDEBUG if ((flatval==679) && j== (nx*ny-2264-(895*nx))){ dumpxyz(flat, x, y, 0, dx, dy); } #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif while ( (pm=(FLAT_TYPE *)fifo4_remove(qdball)) != NULL) /* reset to 0 all descending borders */ *pm = 0; fifo4_lookreset(qdball); while ( (pm=(FLAT_TYPE *)fifo4_remove(qab)) != NULL) /* reset to 0 all ascending borders */ *pm = 0; fifo4_lookreset(qab); while ( (pm=(FLAT_TYPE *)fifo4_remove(qflat)) != NULL) /* reset to REF_PIX_MSB all flat pixels */ *pm = REF_PIX_MSB; fifo4_lookreset(qflat); } } #ifdef XLDEBUG dumpxyz(flat, x, y, 0, dx, dy); #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif /* reset flat image */ for (j=nx*ny*nz; j > 0; j--, pflat0++) if (*pflat0) *pflat0 = FLAT_VAL; #ifdef XLDEBUG dumpxyz(flat, x, y, 0, dx, dy); #endif #ifdef XLDEBUG2 dumpxyz(flat, 0, 0, 0, 44, 44); #endif free_fifo4(q); free_fifo4(qflat); free_fifo4(qdst); free_fifo4(qdb); free_fifo4(qdball); free_fifo4(qab); return imdir; } #undef FLAT_TYPE #undef PR_MAX #undef FLAT_VAL #undef FLAT_MAX #undef FLAT_MAXM1 #undef REF_PIX_MSB #undef FLAT_DB #include "us_undef.h" #include "us_def.h" #define FLAT_TYPE UINT32 #define PR_MAX 255 #define FLAT_MAX 4294967295UL #define FLAT_MAXM1 4294967294UL /* INT32_MAX-1 */ #define FLAT_VAL 4294967293UL /* INT32_MAX-2 */ #define FLAT_DB 4294967292UL /* INT32_MAX-3 */ #define REF_PIX_MSB 0x80000000 #define REF_PIX_LSB 0x000000FF IMAGE *i32_FlatDir(IMAGE *flat, IMAGE *im, int graph) { long int i, j, k, t, nx, ny, nz, shft[27]; FIFO4 *q, *qflat, *qdst, *qdb, *qdball, *qab; FIFO **fifo, **fifot, *pf; IMAGE *imdir; FLAT_TYPE *p, *ptr, *pflat, *pflat0, dcrt, *pm, *pr, *p_k, pr_max, vngb, lowest; PIX_TYPE *pim, *pim0, flatval; UCHAR *pdir0, dir; int delta; double slope, stmp, sqrt2=sqrt(2.0); long int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; #ifdef DEBUG int dx=20, u, n=400; FLAT_TYPE *pwr; int x=10565, y=10112; /* 9176-6215 = 1st bad pixel in tile 2003 (po) 2006-03-14*/ int ofs = (10112*GetImNx(flat))+10565; IMAGE *imwr; int write =0; #endif int graphcrt; if (szgeocompat(im, flat) != NO_ERROR){ (void) sprintf(buf, "i32_FlatDir(): input images must be of same type\n"); errputstr(buf); return NULL; } nx =GetImNx(im); ny =GetImNy(im); nz =GetImNz(im); shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; imdir = (IMAGE *)create_image(t_UCHAR, nx, ny, nz); if (imdir == NULL){ (void)sprintf(buf,"i32_FlatDir(): not enough memory!\n"); errputstr(buf); return NULL; } pim=(PIX_TYPE *)GetImPtr(im); pim0=(PIX_TYPE *)GetImPtr(im); pflat=(FLAT_TYPE *)GetImPtr(flat); pflat0=(FLAT_TYPE *)GetImPtr(flat); /* used for computing offsets */ pdir0 = (UCHAR *)GetImPtr(imdir); for (i=nx*ny;i>0;i--,pflat++) if (*pflat!=0) *pflat=FLAT_VAL; pflat=(FLAT_TYPE *)GetImPtr(flat); /* set shift array */ set_seq_shift(nx, ny, nz, graph, shft); #ifdef BALATON shft[0]=shft1; shft[1]=shft2; shft[2]=shft3; shft[3]=shft4; shft[4]=shft5; shft[5]=shft6; shft[6]=shft7; shft[7]=shft8; #endif q = create_fifo4(500); /* use for geodesic distance computations */ if (q == NULL) return NULL; qflat = create_fifo4(500); /* will hold all pixels of flat region */ if (qflat == NULL) return NULL; qdst = create_fifo4(50); /* used for computing distance transform */ if (qdst == NULL) return NULL; qdb = create_fifo4(10); /* will hold descending borders of flat region (one at a time) */ if (qdb == NULL) return NULL; qdball = create_fifo4(100); /* will hold descending borders of all flat regions */ if (qdball == NULL) return NULL; qab = create_fifo4(10); /* will hold ascending borders of flat region (one at a time) */ if (qab == NULL) return NULL; #ifdef DEBUG dumpxyz(im, x, y, 0, dx, dx); dumpxyz(flat, x, y, 0, dx, dx); #endif for (j=nx*ny*nz; j > 0; j--, pflat++, pim++){ #ifdef DEBUG if ( (pflat-pflat0) == ofs ){ write=1; // dumpxyz(flat, x, y, 0, dx, dx); } #endif if (*pflat == FLAT_VAL){ /* unprocessed flat region */ *pflat=FLAT_MAX; flatval=*pim; fifo4_add(q, (long int)(pflat)); fifo4_add(qflat, (long int)(pflat)); while (fifo4_empty(q) == 0){ /* fill in flat region and initialize queues */ ptr = (FLAT_TYPE *)fifo4_remove(q); for (k = 0; k < graph; k++){ p = ptr + shft[k]; if (*p == FLAT_VAL){ *p=FLAT_MAX; fifo4_add(q, (long int)p); fifo4_add(qflat, (long int)p); } else if (*(pim0+(p-pflat0))>flatval && (*p==0)){ /* external ascending border */ *p=FLAT_MAXM1; fifo4_add(qdst, (long int)p); fifo4_add(qab, (long int)p); } else if ((*(pim0+(p-pflat0))==flatval) && (*p==0)){ /* internal descending border */ *p=FLAT_DB; fifo4_add(qdb, (long int)p); fifo4_add(qdball, (long int)p); } } } #ifdef DEBUG if (write){ // dumpxyz(flat, x, y, 0, dx, dx); imwr=(IMAGE *)imcut(flat, x-10, y-10, 0, x+10, y+10, 0); pwr=(FLAT_TYPE *)GetImPtr(imwr); for(u=0;u 255) printf("dcrt=%d\n", dcrt); if (dcrt==0) dcrt=1; #ifdef DEBUG if (write){ // dumpxyz(flat, x, y, 0, dx, dx); imwr=(IMAGE *)imcut(flat, x-10, y-10, 0, x+10, y+10, 0); pwr=(FLAT_TYPE *)GetImPtr(imwr); for(u=0;u pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("i32_FlatDir(): not enough memory for the FAH: *p_k=%u\n", *p_k); return (NULL); } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; printf("new pr_max value = %d\n", (int) pr_max); } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } } #ifdef DEBUG if (write){ // dumpxyz(flat, x, y, 0, dx, dx); imwr=(IMAGE *)imcut(flat, x-10, y-10, 0, x+10, y+10, 0); pwr=(FLAT_TYPE *)GetImPtr(imwr); for(u=0;u pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("i32_FlatDir(): not enough memory for the FAH: *p_k=%u\n", *p_k); return (NULL); } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(10L); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(10L); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); #ifdef DEBUG if (write){ // dumpxyz(flat, x, y, 0, dx, dx); imwr=(IMAGE *)imcut(flat, x-10, y-10, 0, x+10, y+10, 0); pwr=(FLAT_TYPE *)GetImPtr(imwr); for(u=0;uslope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pm+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pm+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pm+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *(pdir0+(pm-pflat0))=dir; } #ifdef DEBUG if (write){ // dumpxyz(flat, x, y, 0, dx, dx); imwr=(IMAGE *)imcut(imdir, x-10, y-10, 0, x+10, y+10, 0); pwr=(FLAT_TYPE *)GetImPtr(imwr); dumpxyz(imwr, 10, 10, 0, dx, dx); write_tiff(imwr, "d8.tif"); free_image(imwr); } #endif fifo4_lookreset(qdball); while ( (pm=(FLAT_TYPE *)fifo4_remove(qdball)) != NULL) /* reset to 0 all descending borders */ *pm = 0; fifo4_lookreset(qab); while ( (pm=(FLAT_TYPE *)fifo4_remove(qab)) != NULL) /* reset to 0 all ascending borders */ *pm = 0; fifo4_lookreset(qflat); while ( (pm=(FLAT_TYPE *)fifo4_remove(qflat)) != NULL) /* reset to REF_PIX_MSB all flat pixels */ *pm = REF_PIX_MSB; } #ifdef DEBUG write=0; #endif } /* reset flat image */ for (j=nx*ny*nz; j > 0; j--, pflat0++) if (*pflat0) *pflat0 = FLAT_VAL; free_fifo4(q); free_fifo4(qflat); free_fifo4(qdst); free_fifo4(qdb); free_fifo4(qdball); free_fifo4(qab); return imdir; } #undef FLAT_TYPE #undef PR_MAX #undef FLAT_VAL #undef FLAT_MAX #undef FLAT_MAXM1 #undef REF_PIX_MSB #undef FLAT_DB #include "us_undef.h" IMAGE *FlatDir(IMAGE *flat, IMAGE *im, int graph) { /* Compute geodesic distance away from ascending borders on all flat regions, then the geodesic time funtion from descending borders. The flat image must be of type USHORT or INT32 with pixels without drainage set to 65533 (FLAT_VAL) Then compute (and output) the D8 drainage direction for each pixel of the flat regions. First: 06-11-2001 */ /* 2003-02-26 if ((GetImDataType(flat) != t_USHORT) && (GetImDataType(flat) != t_UINT32) && (GetImDataType(flat) != t_INT32)){ (void) sprintf(buf, "FlatDir(): the image of flat areas must be of type USHORT (with flat regions set to 65533) or INT32 (with flat regions set to INT32_MAX-2)\n"); errputstr(buf); return NULL; } */ if ( GetImDataType(im) != t_USHORT ){ (void) sprintf(buf, "FlatDir(IMAGE *flat, IMAGE *im, int graph): the image im must be of type USHORT \n"); errputstr(buf); return NULL; } switch (GetImDataType(flat)){ case t_USHORT: return(us_FlatDir(flat, im, graph)); break; case t_INT32: case t_UINT32: return(i32_FlatDir(flat, im, graph)); break; default: (void)sprintf(buf, "Error in FlatDir(IMAGE *flat, IMAGE *im, int graph): \ invalid ImDataType for flat image: flat areas must be of type USHORT (with flat regions set to 65533) or INT32 (with flat regions set to INT32_MAX-2) (\n"); errputstr(buf); return(NULL); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/flow.c000066400000000000000000001700551467232417700167040ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" /** @defgroup group_dem Digital elevation model processing * Functions dealing with the processing of DEMs. * @{ */ /* ** D8 flow direction (as referred to by \cite{fairfield-leymarie91}) ** Loops have been unrolled for optimal speed. No direction=> dir=0; ** 2001-07-31 */ #include "g_def.h" IMAGE *generic_d8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; long int nx, ny; int delta; double slope, stmp, sqrt2=sqrt(2); IMAGE *imdir; UCHAR *pdir, *pend, dir; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imdir = create_image(t_UCHAR, nx, ny, GetImNz(im)); if (imdir==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pdir = (UCHAR *)GetImPtr(imdir)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((UCHAR *)GetImPtr(imdir))+nx*ny-nx-1; for(; pdirslope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *pdir=dir; } return imdir; } #include "g_undef.h" #include "us_def.h" IMAGE *us_d8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; long int nx, ny; int delta; double slope, stmp, sqrt2=sqrt(2); IMAGE *imdir; UCHAR *pdir, *pend, dir; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imdir = create_image(t_UCHAR, nx, ny, GetImNz(im)); if (imdir==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pdir = (UCHAR *)GetImPtr(imdir)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((UCHAR *)GetImPtr(imdir))+nx*ny-nx-1; for(; pdirslope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *pdir=dir; } return imdir; } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_d8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; long int nx, ny; int delta; double slope, stmp, sqrt2=sqrt(2); IMAGE *imdir; UCHAR *pdir, *pend, dir; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imdir = create_image(t_UCHAR, nx, ny, GetImNz(im)); if (imdir==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pdir = (UCHAR *)GetImPtr(imdir)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((UCHAR *)GetImPtr(imdir))+nx*ny-nx-1; for(; pdirslope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *pdir=dir; } return imdir; } #include "i32_undef.h" #include "f_def.h" IMAGE *f_d8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; long int nx, ny; int delta; double slope, stmp, sqrt2=sqrt(2); IMAGE *imdir; UCHAR *pdir, *pend, dir; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imdir = create_image(t_UCHAR, nx, ny, GetImNz(im)); if (imdir==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pdir = (UCHAR *)GetImPtr(imdir)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((UCHAR *)GetImPtr(imdir))+nx*ny-nx-1; for(; pdirslope){ slope = stmp; dir = 5; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; dir = 6; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; dir = 7; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; dir = 8; lowest=vngb; } } *pdir=dir; } return imdir; } #include "f_undef.h" /* ** Function to process drainage surface area. */ IMAGE *d8(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return generic_d8(im); break; #endif case t_USHORT: return us_d8(im); break; case t_INT32: return i32_d8(im); break; case t_FLOAT: return f_d8(im); break; #ifndef NO_d_IMAGE case t_DOUBLE: return d_d8(im); break; #endif default: (void)sprintf(buf,"d8(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } /* ** D8 slope (as referred to by \cite{fairfield-leymarie91}) ** Loops have been unrolled for optimal speed. ** 2001-07-31 */ #include "g_def.h" #define SLOPE_TYPE float #define t_SLOPE_TYPE t_FLOAT IMAGE *generic_slope8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; long int nx, ny; int delta; /* slope holds twice the square of actual slope */ SLOPE_TYPE slope, stmp, sqrt2=sqrt(2.0); IMAGE *imslope; SLOPE_TYPE *pslope, *pend; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imslope = create_image(t_FLOAT, nx, ny, GetImNz(im)); if (imslope==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pslope = (SLOPE_TYPE *)GetImPtr(imslope)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((SLOPE_TYPE *)GetImPtr(imslope))+nx*ny-nx-1; for(; pslopeslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; lowest=vngb; } } *pslope=slope; } return imslope; } #undef SLOPE_TYPE #undef t_SLOPE_TYPE #include "g_undef.h" #include "us_def.h" #define SLOPE_TYPE float #define t_SLOPE_TYPE t_FLOAT IMAGE *us_slope8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; int nx, ny; int delta; /* slope holds twice the square of actual slope */ SLOPE_TYPE slope, stmp, sqrt2=sqrt(2.0); IMAGE *imslope; SLOPE_TYPE *pslope, *pend; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imslope = create_image(t_FLOAT, nx, ny, GetImNz(im)); if (imslope==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pslope = (SLOPE_TYPE *)GetImPtr(imslope)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((SLOPE_TYPE *)GetImPtr(imslope))+nx*ny-nx-1; for(; pslopeslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; lowest=vngb; } } *pslope=slope; } return imslope; } #undef SLOPE_TYPE #undef t_SLOPE_TYPE #include "us_undef.h" #include "i32_def.h" #define SLOPE_TYPE float #define t_SLOPE_TYPE t_FLOAT IMAGE *i32_slope8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; int nx, ny; int delta; /* slope holds twice the square of actual slope */ SLOPE_TYPE slope, stmp, sqrt2=sqrt(2.0); IMAGE *imslope; SLOPE_TYPE *pslope, *pend; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imslope = create_image(t_FLOAT, nx, ny, GetImNz(im)); if (imslope==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pslope = (SLOPE_TYPE *)GetImPtr(imslope)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((SLOPE_TYPE *)GetImPtr(imslope))+nx*ny-nx-1; for(; pslopeslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; lowest=vngb; } } *pslope=slope; } return imslope; } #undef SLOPE_TYPE #undef t_SLOPE_TYPE #include "i32_undef.h" #include "f_def.h" #define SLOPE_TYPE float #define t_SLOPE_TYPE t_FLOAT IMAGE *f_slope8(IMAGE *im) { int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; int nx, ny; int delta; /* slope holds twice the square of actual slope */ SLOPE_TYPE slope, stmp, sqrt2=sqrt(2.0); IMAGE *imslope; SLOPE_TYPE *pslope, *pend; PIX_TYPE *pim, vngb, lowest; nx=GetImNx(im); ny=GetImNy(im); imslope = create_image(t_FLOAT, nx, ny, GetImNz(im)); if (imslope==NULL) return NULL; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; pslope = (SLOPE_TYPE *)GetImPtr(imslope)+nx+1; pim = ((PIX_TYPE *)GetImPtr(im))+nx+1; pend = ((SLOPE_TYPE *)GetImPtr(imslope))+nx*ny-nx-1; for(; pslopeslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft6); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft7); if (vngbslope){ slope = stmp; lowest=vngb; } } vngb=*(pim+shft8); if (vngbslope){ slope = stmp; lowest=vngb; } } *pslope=slope; } return imslope; } #undef SLOPE_TYPE #undef t_SLOPE_TYPE #include "f_undef.h" /* ** Function to process drainage surface area. */ IMAGE *slope8(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return generic_slope8(im); break; #endif case t_USHORT: return us_slope8(im); break; case t_INT32: return i32_slope8(im); break; case t_FLOAT: return f_slope8(im); break; default: (void)sprintf(buf,"slope8(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } /* ** Function to generate the direction of the gradient. */ #include "g_def.h" ERROR_TYPE generic_dir(IMAGE *im, int graph) { FIFO **fifo; FIFO *pf; PIX_TYPE *p, *pk, *p_i; int *pnb, i, j, k, hcrt, count, hmin, hmax; UCHAR *p_w; long int shft[27]; int box[6]; G_TYPE pg[2]; IMAGE *im_w; generic_min_max(im, pg); hmin = pg[0].generic_val; hmax = pg[1].generic_val; if (hmax>PIX_MAX/2){ (void) printf("dir(): maximum value > PIX_MAX/2: hmax=%d\n", hmax); return ERROR; } if ((pnb = (int *)calloc(hmax + 1, sizeof(int *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); return ERROR; } /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(hmax + 1, sizeof(FIFO *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); free(pnb); return ERROR; } for (i = hmin; i <= hmax; i++){ fifo[i] = alloc_fifo(100); if (fifo[i]==NULL){ for (j = hmin; j < i; j++) clear_fifo(fifo[j]); free((char *)fifo); free((char *)pnb); return ERROR; } } /* initialize FAH */ im_w = minima(im, graph); if (im_w == NULL){ for (i = hmin; i <= hmax; i++) clear_fifo(fifo[i]); free((char *)fifo); free((char *)pnb); return ERROR; } p_i = (PIX_TYPE *)GetImPtr(im); p_w = (UCHAR *)GetImPtr(im_w); LOOPDN(i, GetImNPix(im_w)){ if (*p_w == 1){ fifo_add(fifo[*p_i], (long int)p_i); pnb[*p_i] += 1; *p_i = graph; *p_i |= PIX_MSB; } p_i++; p_w++; } free_image(im_w); /* set shift array */ set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shft); /* boucle principale */ BOX_2D; generic_framebox(im, box, PIX_MSB | graph); for (hcrt = hmin; hcrt <= hmax; hcrt++){ pf = fifo[hcrt]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ count = pnb[hcrt]; pnb[hcrt] = 0; for (i = 0; i < count; i++){ p = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ pk = p + shft[k]; if (*pk & PIX_MSB) continue; fifo_add(fifo[*pk], (long int)pk); pnb[*pk] += 1; *pk = k; *pk |= PIX_MSB; } } } clear_fifo(pf); } } free((char *)fifo); free((char *)pnb); p = (PIX_TYPE *)GetImPtr(im); LOOPDN(i, GetImNPix(im)){ *p ^= PIX_MSB; p++; } return NO_ERROR; } #include "g_undef.h" #include "i32_def.h" ERROR_TYPE i32_dir(IMAGE *im, int graph) { FIFO **fifo; FIFO *pf; PIX_TYPE *p, *pk, *p_i; int *pnb, i, j, k, hcrt, count, hmin, hmax; UCHAR *p_w; long int shft[27]; int box[6]; G_TYPE pg[2]; IMAGE *im_w; i32_min_max(im, pg); hmin = pg[0].i32_val; hmax = pg[1].i32_val; if (hmax>PIX_MAX/2){ (void) printf("dir(): maximum value > PIX_MAX/2\n"); return ERROR; } if ((pnb = (int *)calloc(hmax + 1, sizeof(int *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); return ERROR; } /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(hmax + 1, sizeof(FIFO *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); free(pnb); return ERROR; } for (i = hmin; i <= hmax; i++){ fifo[i] = alloc_fifo(100); if (fifo[i]==NULL){ for (j = hmin; j < i; j++) clear_fifo(fifo[j]); free(pnb); return ERROR; } } /* initialize FAH */ im_w = minima(im, graph); if (im_w == NULL){ for (i = hmin; i <= hmax; i++) clear_fifo(fifo[i]); free((char *)fifo); free((char *)pnb); return ERROR; } p_i = (PIX_TYPE *)GetImPtr(im); p_w = (UCHAR *)GetImPtr(im_w); LOOPDN(i, GetImNPix(im_w)){ if (*p_w == 1){ fifo_add(fifo[*p_i], (long int)p_i); pnb[*p_i] += 1; *p_i = graph; *p_i |= PIX_MSB; } p_i++; p_w++; } free_image(im_w); /* set shift array */ set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shft); /* boucle principale */ BOX_2D; i32_framebox(im, box, PIX_MSB | graph); for (hcrt = hmin; hcrt <= hmax; hcrt++){ pf = fifo[hcrt]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ count = pnb[hcrt]; pnb[hcrt] = 0; for (i = 0; i < count; i++){ p = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ pk = p + shft[k]; if (*pk & PIX_MSB) continue; fifo_add(fifo[*pk], (long int)pk); pnb[*pk] += 1; *pk = k; *pk |= PIX_MSB; } } } clear_fifo(pf); } } free((char *)fifo); free((char *)pnb); p = (PIX_TYPE *)GetImPtr(im); LOOPDN(i, GetImNPix(im)){ *p ^= PIX_MSB; p++; } return NO_ERROR; } #include "i32_undef.h" #include "us_def.h" ERROR_TYPE us_dir(IMAGE *im, int graph) { FIFO **fifo; FIFO *pf; PIX_TYPE *p, *pk, *p_i; int *pnb, i, j, k, hcrt, count, hmin, hmax; UCHAR *p_w; long int shft[27]; int box[6]; G_TYPE pg[2]; IMAGE *im_w; us_min_max(im, pg); hmin = pg[0].us_val; hmax = pg[1].us_val; if (hmax>PIX_MAX/2){ (void) printf("dir(): maximum value > PIX_MAX/2\n"); return ERROR; } if ((pnb = (int *)calloc(hmax + 1, sizeof(int *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); return ERROR; } /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(hmax + 1, sizeof(FIFO *))) == NULL){ (void) printf("dir(): not enough memory for the FAH\n"); free(pnb); return ERROR; } for (i = hmin; i <= hmax; i++){ fifo[i] = alloc_fifo(100); if (fifo[i]==NULL){ for (j = hmin; j < i; j++) clear_fifo(fifo[j]); free(pnb); return ERROR; } } /* initialize FAH */ im_w = minima(im, graph); if (im_w == NULL){ for (i = hmin; i <= hmax; i++) clear_fifo(fifo[i]); free((char *)fifo); free((char *)pnb); return ERROR; } p_i = (PIX_TYPE *)GetImPtr(im); p_w = (UCHAR *)GetImPtr(im_w); LOOPDN(i, GetImNPix(im_w)){ if (*p_w == 1){ fifo_add(fifo[*p_i], (long int)p_i); pnb[*p_i] += 1; *p_i = graph; *p_i |= PIX_MSB; } p_i++; p_w++; } free_image(im_w); /* set shift array */ set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shft); /* boucle principale */ BOX_2D; us_framebox(im, box, PIX_MSB | graph); for (hcrt = hmin; hcrt <= hmax; hcrt++){ pf = fifo[hcrt]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ count = pnb[hcrt]; pnb[hcrt] = 0; for (i = 0; i < count; i++){ p = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ pk = p + shft[k]; if (*pk & PIX_MSB) continue; fifo_add(fifo[*pk], (long int)pk); pnb[*pk] += 1; *pk = k; *pk |= PIX_MSB; } } } clear_fifo(pf); } } free((char *)fifo); free((char *)pnb); p = (PIX_TYPE *)GetImPtr(im); LOOPDN(i, GetImNPix(im)){ *p ^= PIX_MSB; p++; } return NO_ERROR; } #include "us_undef.h" /* ** Function to process drainage surface area. */ ERROR_TYPE dir(IMAGE *im, int graph) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: generic_dir(im, graph); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: uc_dir(im, graph); break; #endif case t_USHORT: us_dir(im, graph); break; #ifndef NO_s_IMAGE case t_SHORT: s_dir(im, graph); break; #endif #ifndef NO_u32_IMAGE case t_UINT32: u32_dir(im, graph); break; #endif case t_INT32: i32_dir(im, graph); break; #ifndef NO_f_IMAGE case t_FLOAT: f_dir(im, graph); break; #endif #ifndef NO_d_IMAGE case t_DOUBLE: d_dir(im, graph); break; #endif default: (void)sprintf(buf,"dir(im, graph): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /* ** Function to process drainage surface area (CDA) */ IMAGE *flow(IMAGE *imin, int graph) { UCHAR *p_dir; UINT32 *p, *p_area, *p_srt; int thedir; long int i, shft[27]; IMAGE *im, *imhst, *imrsum, *imsort, *im_w, *imtmp; G_TYPE gval; im=(IMAGE *)copy_image(imin); imhst = histo1d(im); if (imhst==NULL) return(NULL); imrsum = (IMAGE *)rsum(imhst); free_image(imhst); if (imrsum==NULL) return(NULL); imsort = (IMAGE *)sort_offset(im, imrsum); free_image(imrsum); if (imsort==NULL) return(NULL); /* original code: flow directions collected during a flooding procedure: if (dir(im, graph) != NO_ERROR){ free_image(imsort); return NULL; } imtmp = (IMAGE *)to_uchar(im); old style to_uchar (now destructive) free_image(im); ** End of original programme */ /* D8 flow directions are a way better: */ if ((imtmp=d8(im)) == NULL){ free_image(imsort); return NULL; } free_image(im); im_w = create_image(t_UINT32, GetImNx(imtmp) ,GetImNy(imtmp), GetImNz(imtmp)); gval.u32_val=1; blank(im_w, gval); p_srt = ((UINT32 *)GetImPtr(imsort))+GetImNPix(imsort); p_dir = (UCHAR *)GetImPtr(imtmp); p_area = (UINT32 *)GetImPtr(im_w); /* Take graph into account */ setinvseqshift(GetImNx(imtmp), GetImNy(imtmp), GetImNz(imtmp), graph, shft); shft[5] = -GetImNx(imtmp)-1; shft[3] = -GetImNx(imtmp); shft[7] = -GetImNx(imtmp)+1; shft[1] = -1; shft[0]= 0; shft[2] = +1; shft[6] = GetImNx(imtmp)-1; shft[4] = +GetImNx(imtmp); shft[8] = GetImNx(imtmp)+1; /* here we go */ LOOPDN (i, GetImNPix(imtmp)){ p_srt--; thedir = *(p_dir + *p_srt); if (thedir != 0){ /* was graph with directions from flooding ! */ p = p_area + *p_srt; *(p + shft[thedir]) += *p; } } free_image(imsort); free_image(imtmp); return im_w; } /* ** Function to process drainage surface area (CDA) */ IMAGE *flownew(IMAGE *imin, IMAGE *imdir, int graph) { /* flow directions are passed on to the procedure */ UCHAR *p_dir; UINT32 *p, *p_area, *p_srt; int thedir; long int i, shft[27]; IMAGE *imhst, *imrsum, *imsort, *im_w; G_TYPE gval; imhst = histo1d(imin); if (imhst==NULL) return(NULL); imrsum = (IMAGE *)rsum(imhst); free_image(imhst); if (imrsum==NULL) return(NULL); imsort = (IMAGE *)sort_offset(imin, imrsum); free_image(imrsum); if (imsort==NULL) return(NULL); im_w = create_image(t_UINT32, GetImNx(imdir) ,GetImNy(imdir), GetImNz(imdir)); gval.u32_val=1; blank(im_w, gval); p_srt = ((UINT32 *)GetImPtr(imsort))+GetImNPix(imsort); p_dir = (UCHAR *)GetImPtr(imdir); p_area = (UINT32 *)GetImPtr(im_w); /* Take graph into account */ setinvseqshift(GetImNx(imdir), GetImNy(imdir), GetImNz(imdir), graph, shft); shft[5] = -GetImNx(imdir)-1; shft[3] = -GetImNx(imdir); shft[7] = -GetImNx(imdir)+1; shft[1] = -1; shft[0]= 0; shft[2] = +1; shft[6] = GetImNx(imdir)-1; shft[4] = +GetImNx(imdir); shft[8] = GetImNx(imdir)+1; /* here we go */ LOOPDN (i, GetImNPix(imdir)){ p_srt--; thedir = *(p_dir + *p_srt); if (thedir != 0){ /* was graph with directions from flooding ! */ p = p_area + *p_srt; *(p + shft[thedir]) += *p; } } free_image(imsort); return im_w; } #define CDA_TYPE INT32 IMAGE *cda(IMAGE *dir, int graph) { /* output CDA using only image of directions (assuming 0 directions on border) */ IMAGE *imn; /* image giving number of pixels draining towards each pixel */ IMAGE *imcda; UCHAR *pdir, *pdir0, maxi; UCHAR *pn, *pn0; CDA_TYPE *pcda0; long int nx, ny, nz; long int i, ofs, ofss; int shft[9]; int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; FIFO4 *q; G_TYPE *pg; int box[6]; /* check data type and pixel value range of image dir */ if (GetImDataType(dir) != t_UCHAR){ (void)sprintf(buf,"*cda(IMAGE *dir, int graph): image dir must be of type t_UCHAR\n"); errputstr(buf); return NULL; } pg = min_max(dir); if (pg == NULL) return(NULL); maxi = pg[1].generic_val; free((char *)pg); if (maxi>8){ (void)sprintf(buf,"*cda(IMAGE *dir, int graph): drainage directions must be in {0,...,8}\n"); errputstr(buf); return NULL; } nx =GetImNx(dir); ny =GetImNy(dir); nz =GetImNz(dir); shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; shft[5]=shft5; shft[3]=shft3; shft[7]=shft7; shft[1]=shft1; shft[0]= 0; shft[2]=shft2; shft[6]=shft6; shft[4]=shft4; shft[8]=shft8; imn = create_image(t_UCHAR, nx, ny, nz); if (imn==NULL) return NULL; imcda = create_image(t_INT32, nx, ny, nz); if (imcda==NULL) return NULL; i32_blank(imcda, 1); /* initialize CDA to 1 (homogeneous rain) */ BOX_2D; uc_framebox(dir,box,0); /* make sure border is set to 0 */ q = create_fifo4(nx+ny+nz); /* use for geodesic distance computations */ if (q == NULL) return NULL; pdir0 = (UCHAR *)GetImPtr(dir); pn0 = (UCHAR *)GetImPtr(imn); pcda0 = (CDA_TYPE *)GetImPtr(imcda); /* initialize imn and queue */ pdir = (UCHAR *)GetImPtr(dir); pn = (UCHAR *)GetImPtr(imn); for (i=nx*ny*nz; i>0; i--, pdir++, pn++){ if (*pdir){ if (*(pdir+shft1)==2) *pn+=1; if (*(pdir+shft2)==1) *pn+=1; if (*(pdir+shft3)==4) *pn+=1; if (*(pdir+shft4)==3) *pn+=1; if (graph==8){ if (*(pdir+shft5)==8) *pn+=1; if (*(pdir+shft6)==7) *pn+=1; if (*(pdir+shft7)==6) *pn+=1; if (*(pdir+shft8)==5) *pn+=1; } if (*pn == 0) /* no pixel drain to this pixel */ fifo4_add(q, (long int)(pn-pn0)); } } /* simulate ordered flow */ while (fifo4_empty(q) == 0){ ofs = fifo4_remove(q); ofss = ofs+shft[*(pdir0+ofs)]; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && *(pdir0+ofss) ) fifo4_add(q, (long int)(ofss)); } free_fifo4(q); free_image(imn); return imcda; } #undef CDA_TYPE #include "us_def.h" /* for thresh image */ #define CDA_TYPE INT32 IMAGE *us_stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir) { long int i, j; int shft[9]; CDA_TYPE *pcda=(CDA_TYPE *)GetImPtr(cda); PIX_TYPE *pthresh=(PIX_TYPE *)GetImPtr(thresh); unsigned char *pdir=(unsigned char *)GetImPtr(dir), *pout; long int npix=GetImNPix(cda); int nx=GetImNx(cda); IMAGE *out; if ( ( GetImDataType(cda) != t_INT32 ) || ( GetImDataType(dir) != t_UCHAR ) ){ (void)sprintf(buf,"stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir): cda image must be of type INT32, thresh image must be of type USHORT or UINT32, dir image must be of type UCHAR!\n"); errputstr(buf); return NULL; } if ( ( szgeocompat(cda, thresh) != NO_ERROR ) || ( szgeocompat(cda, dir) != NO_ERROR ) ){ (void)sprintf(buf,"stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir): cda, thresh, and dir images must have the same x-y dimensions!\n"); errputstr(buf); return NULL; } shft[5]= -nx-1; shft[3] = -nx; shft[7] = -nx+1; shft[1]= -1; shft[0]=0; shft[2] = +1; shft[6]= nx-1; shft[4] = +nx; shft[8] = nx+1; out = create_image(t_UCHAR, GetImNx(cda), GetImNy(cda), GetImNz(cda)); if (out == NULL){ (void)sprintf(buf,"stratify(): not enough memory!\n"); errputstr(buf); return(out); } pout=(unsigned char *)GetImPtr(out); for (i=0; i=pthresh[i]) && (pout[i]==0)){ /* initiate channel */ pout[i]=1; j=i+shft[pdir[i]]; while ( pdir[j] && (pout[j]!=1) ){ pout[j]=1; j+=shft[pdir[j]]; } } } return out; } #undef CDA_TYPE #include "us_undef.h" #include "i32_def.h" /* for thresh image */ #define CDA_TYPE INT32 IMAGE *i32_stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir) { long int i, j; int shft[9]; CDA_TYPE *pcda=(CDA_TYPE *)GetImPtr(cda); PIX_TYPE *pthresh=(PIX_TYPE *)GetImPtr(thresh); unsigned char *pdir=(unsigned char *)GetImPtr(dir), *pout; long int npix=GetImNPix(cda); int nx=GetImNx(cda); IMAGE *out; if ( ( GetImDataType(cda) != t_INT32 ) || ( GetImDataType(dir) != t_UCHAR ) ){ (void)sprintf(buf,"stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir): cda image must be of type INT32, thresh image must be of type USHORT or INT32, dir image must be of type UCHAR!\n"); errputstr(buf); return NULL; } if ( ( szgeocompat(cda, thresh) != NO_ERROR ) || ( szgeocompat(cda, dir) != NO_ERROR ) ){ (void)sprintf(buf,"stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir): cda, thresh, and dir images must have the same x-y dimensions!\n"); errputstr(buf); return NULL; } shft[5]= -nx-1; shft[3] = -nx; shft[7] = -nx+1; shft[1]= -1; shft[0]=0; shft[2] = +1; shft[6]= nx-1; shft[4] = +nx; shft[8] = nx+1; out = create_image(t_UCHAR, GetImNx(cda), GetImNy(cda), GetImNz(cda)); if (out == NULL){ (void)sprintf(buf,"stratify(): not enough memory!\n"); errputstr(buf); return(out); } pout=(unsigned char *)GetImPtr(out); for (i=0; i=pthresh[i]) && (pout[i]==0)){ /* initiate channel */ pout[i]=1; j=i+shft[pdir[i]]; while ( pdir[j] && (pout[j]!=1) ){ pout[j]=1; j+=shft[pdir[j]]; } } } return out; } #undef CDA_TYPE #include "i32_undef.h" /* ** Function to process drainage surface area. */ IMAGE *stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir) { switch (GetImDataType(thresh)){ case t_USHORT: return(us_stratify(cda, thresh, dir)); break; case t_INT32: return(i32_stratify(cda, thresh, dir)); break; default: (void)sprintf(buf,"stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir): invalid pixel type for thresh image\n"); errputstr(buf); return(NULL); } return(NULL); } #include "uc_def.h" IMAGE *uc_dinf(IMAGE *im) { int k, kmax=0; int box[6]; MIALFLOAT ac[8]= { 0.0, PI/2.0, PI/2.0, PI, PI, 3.0*PI/2.0, 3.0*PI/2.0, 2.0*PI }; int af[8]= { 1, -1 , 1, -1, 1, -1, 1, -1 }; long int i, shft1[8], shft2[8], e0, npix; int nx; int s1, s2; MIALFLOAT s, smax, pi=PI, pio2=PI/2.0, pio4=PI/4.0; PIX_TYPE *pim; MIALFLOAT *pdir, r, rmax=0.0; IMAGE *imdir; /* frame input to avoid border overflows */ BOX_2D; if ( generic_addframebox(im, box, PIX_MIN) == ERROR) return NULL; nx=GetImNx(im); /* create output image */ imdir = create_image(t_FLOAT, nx, GetImNy(im), GetImNz(im)); if (imdir==NULL) return NULL; /* search the facet with steepest slope */ shft1[0]=1; shft1[1]=-nx; shft1[2]=-nx; shft1[3]=-1; shft1[4]=-1; shft1[5]=nx; shft1[6]=nx; shft1[7]=1; shft2[0]=-nx+1; shft2[1]=-nx+1;shft2[2]=-nx-1; shft2[3]=-nx-1; shft2[4]=nx-1; shft2[5]=nx-1; shft2[6]=nx+1; shft2[7]=nx+1; /* here we go */ pim=(PIX_TYPE *)GetImPtr(im); pdir=(MIALFLOAT *)GetImPtr(imdir); npix=GetImNPix(im); for (i=0; i0) r=pio4; else r=-pio4; } else{ r=(float)atan( (double)s2/s1); if (s1<0) r+=pi; } if (r<=0.0){ r=0.0; s=s1; } else if (r>=pio4){ r=pio4; s=(e0-*(pim+shft2[k]))/sqrt(2.0); } else s=sqrt(s1*s1+s2*s2); if (s>smax){ smax=s; rmax=r; kmax=k; } } if (smax>0.0) r=(float)((af[kmax]*rmax)+ac[kmax]); else r=-1.0; } else r=-1.0; *pdir=r; } subframebox(im, box); subframebox(imdir, box); return imdir; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_dinf(IMAGE *im) { int k, kmax=0; int box[6]; MIALFLOAT ac[8]= { 0.0, PI/2.0, PI/2.0, PI, PI, 3.0*PI/2.0, 3.0*PI/2.0, 2.0*PI }; int af[8]= { 1, -1 , 1, -1, 1, -1, 1, -1 }; long int i, shft1[8], shft2[8], e0, npix; int nx; int s1, s2; MIALFLOAT s, smax, pi=PI, pio2=PI/2.0, pio4=PI/4.0; PIX_TYPE *pim; MIALFLOAT *pdir, r, rmax=0.0; IMAGE *imdir; /* frame input to avoid border overflows */ BOX_2D; if (us_addframebox(im, box, PIX_MIN) == ERROR) return NULL; nx=GetImNx(im); /* create output image */ imdir = create_image(t_FLOAT, nx, GetImNy(im), GetImNz(im)); if (imdir==NULL) return NULL; /* search the facet with steepest slope */ shft1[0]=1; shft1[1]=-nx; shft1[2]=-nx; shft1[3]=-1; shft1[4]=-1; shft1[5]=nx; shft1[6]=nx; shft1[7]=1; shft2[0]=-nx+1; shft2[1]=-nx+1;shft2[2]=-nx-1; shft2[3]=-nx-1; shft2[4]=nx-1; shft2[5]=nx-1; shft2[6]=nx+1; shft2[7]=nx+1; pim=(PIX_TYPE *)GetImPtr(im); pdir=(MIALFLOAT *)GetImPtr(imdir); npix=GetImNPix(im); for (i=0; i0) r=pio4; else r=-pio4; } else{ r=(float)atan( (double)s2/s1); if (s1<0) r+=pi; } if (r<=0.0){ r=0.0; s=s1; } else if (r>=pio4){ r=pio4; s=(e0-*(pim+shft2[k]))/sqrt(2.0); } else s=sqrt(s1*s1+s2*s2); if (s>smax){ smax=s; rmax=r; kmax=k; } } if (smax>0.0) r=(float)((af[kmax]*rmax)+ac[kmax]); else r=-1.0; } else r=-1.0; *pdir=r; } subframebox(im, box); subframebox(imdir, box); return imdir; } #include "us_undef.h" IMAGE *dinf(IMAGE *im) { /* ** authors: P. Soille 2004-04-29---2004-05-01 ** IMAGE *im: an image node ** comment: adapted from \citep{tarboton97}. */ switch (GetImDataType(im)){ case t_UCHAR: return uc_dinf(im); break; case t_USHORT: return us_dinf(im); break; default: (void)sprintf(buf,"dinf(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } #define CDA_TYPE MIALFLOAT IMAGE *cdainf(IMAGE *dir) { /* output CDA using only image of directions (assuming -1 directions on border) */ IMAGE *imn; /* image giving number of pixels draining towards each pixel */ IMAGE *imcda; UCHAR *pn, *pn0; CDA_TYPE *pcda0; MIALFLOAT *pdir, *pdir0, dircrt; MIALFLOAT pi=PI, pio2=PI/2.0, pio34=3.0*PI/4.0, pio4=PI/4.0, \ pio54=5.0*PI/4.0, pio32=3.0*PI/2.0, pio74=7.0*PI/4.0; long int nx, ny, nz; long int i, ofs, ofss; int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; FIFO4 *q; int box[6]; /* check data type and pixel value range of image dir */ if (GetImDataType(dir) != t_FLOAT){ (void)sprintf(buf,"*cdainf(IMAGE *dir): image dir must be of type t_FLOAT\n"); errputstr(buf); return NULL; } nx =GetImNx(dir); ny =GetImNy(dir); nz =GetImNz(dir); shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; imn = create_image(t_UCHAR, nx, ny, nz); if (imn==NULL) return NULL; imcda = create_image(t_FLOAT, nx, ny, nz); if (imcda==NULL) return NULL; f_blank(imcda, 1.0); /* initialize CDA to 1 (homogeneous rain, constant area pixel) */ BOX_2D; f_framebox(dir,box,-1.0); /* make sure border is set to -1.0 */ q = create_fifo4(nx+ny+nz); /* use for geodesic distance computations */ if (q == NULL) return NULL; pdir0 = (MIALFLOAT *)GetImPtr(dir); pn0 = (UCHAR *)GetImPtr(imn); pcda0 = (CDA_TYPE *)GetImPtr(imcda); /* initialize imn and queue */ pdir = (MIALFLOAT *)GetImPtr(dir); pn = (UCHAR *)GetImPtr(imn); for (i=nx*ny*nz; i>0; i--, pdir++, pn++){ if (*pdir>=0.0){ /* 4-neighbours */ if ( (*(pdir+shft1) < pio4) && (*(pdir+shft1) >= 0.0) ) *pn+=1; if ( *(pdir+shft1) > pio74) *pn+=1; if ( (*(pdir+shft2) > pio34) && (*(pdir+shft2) < pio54)) *pn+=1; if ( (*(pdir+shft3) > pio54) && (*(pdir+shft3) < pio74)) *pn+=1; if ( (*(pdir+shft4) > pio4) && (*(pdir+shft4) < pio34)) *pn+=1; /* 8-neighbours */ if ( (*(pdir+shft5) > pio32)) *pn+=1; if ( (*(pdir+shft6) < pio2) && (*(pdir+shft6) > 0.0) ) *pn+=1; if ( (*(pdir+shft7) > pi) && (*(pdir+shft7) < pio32) ) *pn+=1; if ( (*(pdir+shft8) > pio2) && (*(pdir+shft8) < pi) ) *pn+=1; if (*pn == 0) /* no pixel drain to this pixel */ fifo4_add(q, (long int)(pn-pn0)); } } /* generic_dumpxyz(imn, 5, 5, 0, 10); */ write_tiff(imn, "/tmp/imnin.tif"); /* simulate ordered flow */ while (fifo4_empty(q) == 0){ /* generic_dumpxyz(imn, 5, 5, 0, 10); f_dumpxyz(imcda, 5, 5, 0, 10);*/ ofs = fifo4_remove(q); dircrt=*(pdir0+ofs); /* in radians */ if (dircrt==0.0){ ofss = ofs+shft2; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft2; *(pcda0+ofss) += dircrt/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio4){ ofss = ofs+shft7; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft7; *(pcda0+ofss) += (dircrt-pio4)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio2){ ofss = ofs+shft3; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft3; *(pcda0+ofss) += (dircrt-pio2)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio34){ ofss = ofs+shft5; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft5; *(pcda0+ofss) += (dircrt-pio34)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pi){ ofss = ofs+shft1; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft1; *(pcda0+ofss) += (dircrt-pi)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio54){ ofss = ofs+shft6; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft6; *(pcda0+ofss) += (dircrt-pio54)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio32){ ofss = ofs+shft4; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft4; *(pcda0+ofss) += (dircrt-pio32)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else if (dircrt==pio74){ ofss = ofs+shft8; *(pcda0+ofss) += *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } else{ /* last octant */ ofss = ofs+shft2; *(pcda0+ofss) += (2.0*pi-dircrt)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); ofss = ofs+shft8; *(pcda0+ofss) += (dircrt-pio74)/pio4 * *(pcda0+ofs); *(pn0+ofss) -= 1; if ((*(pn0+ofss) == 0) && ( *(pdir0+ofss) >= 0.0) ) fifo4_add(q, (long int)(ofss)); } /* printf("dircrt=%f, ofss=%d, *(pn0+ofss)=%d\n", dircrt, ofss, *(pn0+ofss)); */ } write_tiff(imn, "/tmp/imnout.tif"); free_fifo4(q); free_image(imn); return imcda; } #undef CDA_TYPE #include "uc_def.h" IMAGE *uc_slopeinf(IMAGE *im) { long int i; int k; int box[6]; long int shft1[8], shft2[8], e0, npix; int nx; int s1, s2; MIALFLOAT s, smax, pi=PI, pio2=PI/2.0, pio4=PI/4.0; PIX_TYPE *pim; MIALFLOAT *pdir, r; IMAGE *imdir; /* frame input to avoid border overflows */ BOX_2D; if ( generic_addframebox(im, box, PIX_MIN) == ERROR) return NULL; nx=GetImNx(im); /* create output image */ imdir = create_image(t_FLOAT, nx, GetImNy(im), GetImNz(im)); if (imdir==NULL) return NULL; /* search the facet with steepest slope */ shft1[0]=1; shft1[1]=-nx; shft1[2]=-nx; shft1[3]=-1; shft1[4]=-1; shft1[5]=nx; shft1[6]=nx; shft1[7]=1; shft2[0]=-nx+1; shft2[1]=-nx+1;shft2[2]=-nx-1; shft2[3]=-nx-1; shft2[4]=nx-1; shft2[5]=nx-1; shft2[6]=nx+1; shft2[7]=nx+1; pim=(PIX_TYPE *)GetImPtr(im); pdir=(MIALFLOAT *)GetImPtr(imdir); npix=GetImNPix(im); for (i=0; i0) r=pio4; else r=-pio4; } else{ r=(float)atan( (double)s2/s1); if (s1<0) r+=pi; } if (r<=0.0){ r=0.0; s=s1; } else if (r>=pio4){ r=pio4; s=(e0-*(pim+shft2[k]))/sqrt(2.0); } else s=sqrt(s1*s1+s2*s2); if (s>smax){ smax=s; } } } *pdir=smax; } subframebox(im, box); subframebox(imdir, box); return imdir; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_slopeinf(IMAGE *im) { long int i; int k; int box[6]; long int shft1[8], shft2[8], e0, npix; int nx; int s1, s2; MIALFLOAT s, smax, pi=PI, pio2=PI/2.0, pio4=PI/4.0; PIX_TYPE *pim; MIALFLOAT *pdir, r; IMAGE *imdir; /* frame input to avoid border overflows */ BOX_2D; if ( us_addframebox(im, box, PIX_MIN) == ERROR) return NULL; nx=GetImNx(im); /* create output image */ imdir = create_image(t_FLOAT, nx, GetImNy(im), GetImNz(im)); if (imdir==NULL) return NULL; /* search the facet with steepest slope */ shft1[0]=1; shft1[1]=-nx; shft1[2]=-nx; shft1[3]=-1; shft1[4]=-1; shft1[5]=nx; shft1[6]=nx; shft1[7]=1; shft2[0]=-nx+1; shft2[1]=-nx+1;shft2[2]=-nx-1; shft2[3]=-nx-1; shft2[4]=nx-1; shft2[5]=nx-1; shft2[6]=nx+1; shft2[7]=nx+1; pim=(PIX_TYPE *)GetImPtr(im); pdir=(MIALFLOAT *)GetImPtr(imdir); npix=GetImNPix(im); for (i=0; i0) r=pio4; else r=-pio4; } else{ r=(float)atan( (double)s2/s1); if (s1<0) r+=pi; } if (r<=0.0){ r=0.0; s=s1; } else if (r>=pio4){ r=pio4; s=(e0-*(pim+shft2[k]))/sqrt(2.0); } else s=sqrt(s1*s1+s2*s2); if (s>smax){ smax=s; } } } *pdir=smax; } subframebox(im, box); subframebox(imdir, box); return imdir; } #include "us_undef.h" IMAGE *slopeinf(IMAGE *im) { /* ** authors: P. Soille 2004-05-01 ** IMAGE *im: an image node ** comment: adapted from \citep{tarboton97}. */ switch (GetImDataType(im)){ case t_UCHAR: return uc_slopeinf(im); break; case t_USHORT: return us_slopeinf(im); break; default: (void)sprintf(buf,"slopeinf(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } #include "us_def.h" ERROR_TYPE us_cboutlet(IMAGE *outlet, IMAGE *d8) { UCHAR *pdir; PIX_TYPE *plbl; long int nx, k; unsigned long int npix, ofs; long int i, shft[9]; FIFO4 *q; nx=GetImNx(outlet); npix=GetImNPix(outlet); q = create_fifo4((long int) (npix/1000+1000) ); if (q == NULL) return ERROR; /* reflected flow directions, see d8 for original directions */ shft[8] = -nx-1; shft[4] = -nx; shft[6] = -nx+1; shft[2] = -1; shft[1] = +1; shft[7] = nx-1; shft[3] = +nx; shft[5] = nx+1; pdir = (UCHAR *)GetImPtr(d8); plbl = ((PIX_TYPE *)GetImPtr(outlet)); for(i=0;i1){ conf=1; for(k=1;k<9;k++){ if (pdir[ofs+shft[k]]==k){ pdir[ofs+shft[k]]|=0x80; if (plbl[ofs+shft[k]]==RIV){ plbl[ofs+shft[k]]=plbl[ofs]+conf++; } else{ plbl[ofs+shft[k]]=plbl[ofs]; } fifo4_add(q, (long int)(ofs+shft[k])); } } } else{ for(k=1;k<9;k++){ if (pdir[ofs+shft[k]]==k){ pdir[ofs+shft[k]]|=0x80; plbl[ofs+shft[k]]=plbl[ofs]; fifo4_add(q, (long int)(ofs+shft[k])); } } } } } } #ifdef OPENMP #pragma omp parallel for #endif for(i=0;i8){ // tile 2003 printf("ofs=%d\n", (int)ofs); dumpxyz(d8,i-(int)(i/nx)*nx,(int)(i/nx),0,10,10); } if(pdir[i]){ flag=1; for(k=1;k<9;k++){ if (pdir[i+bshft[k]]==k){ flag=0; break; } } if (flag) fifo4_add(q, (long int)(i)); } } /* recursive ordered propagation */ ocrt=-1; do{ while (fifo4_empty(qconf) == 0){ ofs=fifo4_remove(qconf); if(pdir[ofs]&0x80) /* different order confluence */ pdir[ofs]^=0x80; else{ /* potential same order confluence */ pdir[ofs]^=0x40; soc=1; for(k=1;k<9;k++){ if (pdir[ofs+bshft[k]]==k){ soc=0; /* not same order confluence */ break; } } if (soc){ fifo4_add(q, (long int)(ofs)); } } } ocrt++; // printf("ocrt=%d\n", (int) ocrt+1); while (fifo4_empty(q) == 0){ ofs=fifo4_remove(q); // if(ofs==115371783){ if(ofs==76325582){ printf("ofs=%d\n", (int)ofs); dumpxyz(d8,ofs-(int)(ofs/nx)*nx,(int)(ofs/nx),0,10,10); } if(pdir[ofs]>8){ printf("ofs=%d\n", (int)ofs); dumpxyz(d8,ofs-(int)(ofs/nx)*nx,(int)(ofs/nx),0,10,10); continue; } ofsd8=ofs+fshft[pdir[ofs]]; if(pdir[ofsd8]==0){ /* end of stream */ pdir[ofs]=order[ocrt]; continue; } pdir[ofs]=order[ocrt]; if(pdir[ofsd8]&0x80){ /* potential same order confluence */ pdir[ofsd8]^=0xC0; } else if (pdir[ofsd8]<9){ conf=0; for(k=1;k<9;k++){ if ((pdir[ofsd8+bshft[k]]& 0x3F)==k){ conf=1; break; } } if(conf){ /* confluence reached */ pdir[ofsd8]|=0x80; fifo4_add(qconf, (long int)(ofsd8)); } else fifo4_add(q, (long int)(ofsd8)); } } } while ( fifo4_empty(qconf) == 0); #ifdef OPENMP #pragma omp parallel for #endif for(i=0;i. ***********************************************************************/ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif /** \defgroup group_format Type conversions * Functions related to the image type conversions. * @{ */ /* One has to be careful with data type conversions where the values are not just cast but also rescaled. Check consistency! Think about sign when going from signed to unsigned. When planning parallel for with openmp beware that it does NOT work with destructive conversion (20120329) */ /*************************************************************************/ /* */ IMAGE *to_tiff1bitpp(IMAGE *im) { IMAGE *imout; UCHAR *ptmp, *ptr_compac; int nx=GetImNx(im), nlin=GetImNlin(im); int i, j, k, der, reste; if (GetImDataType(im) != t_UCHAR){ (void)sprintf(buf,"IMAGE *to_tiff1bitpp(im): not t_UCHAR image!\n"); errputstr(buf); errputstr(buf); return(NULL); } /* create output image */ imout = create_image(t_TIFFONEBITPERPIXEL, GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"IMAGE *to_tiff1bitpp(im): not enough memory!\n"); errputstr(buf); return(NULL); } ptmp = (UCHAR *)GetImPtr(imout); ptr_compac = (UCHAR *)GetImPtr(im); der = nx / 8; reste = nx % 8; reste = 8 - reste; for (k = 0; k < nlin; k++){ for (i = 0; i < der; i++){ *ptmp = (*ptr_compac++)<<7; for (j = 6; j >= 0; j--) *ptmp |= (*ptr_compac++)<= reste; i--) *ptmp |= (*ptr_compac++)<>j); } } if (reste){ for (j=0; j < reste; j++){ p2[BITPERWORD*i+j+k] = *p1 & (W_MSB>>j); } p1++; } } return(NO_ERROR); } #include "b_undef.h" #include "us_def.h" ERROR_TYPE us_to_uchar(IMAGE *im) { mia_size_t i, npix; unsigned long int nbyte; UCHAR *p2; PIX_TYPE *p1, mini, maxi; double range; G_TYPE *pg; p1 = (PIX_TYPE *)GetImPtr(im); p2 = (UCHAR *)GetImPtr(im); npix = GetImNPix(im); pg = min_max(im); if (pg == NULL) return(ERROR); mini = pg[0].us_val; maxi = pg[1].us_val; free((char *)pg); range = (double)maxi - mini; #if SIGNED if ( (maxi <= UCHAR_MAX) && (mini >= UCHAR_MIN) ) #else if (maxi <= UCHAR_MAX) #endif for (i=0; i= UCHAR_MIN) ) for (i=0; i= UCHAR_MIN) ) for (i=0; i= UCHAR_MIN) ) for (i=0; i= UCHAR_MIN) ) for (i=0; i= UCHAR_MIN) ) for (i=0; i= UCHAR_MIN) ) for (i=0; i= USHORT_MIN) ) for (i=0; iDataType=t_FLOAT; return NO_ERROR; } /*************************************************************************/ /* swap bytes (for LITTLE<->BIG ENDIAN conversions) */ /*************************************************************************/ /* ** Function to swap long types. */ void swap_long(INT32 *pl) { union mylong { INT32 lo; struct { char c1, c2, c3, c4; } ch; } ll; char ch_tmp; ll.lo = *pl; ch_tmp = ll.ch.c1; ll.ch.c1 = ll.ch.c4; ll.ch.c4 = ch_tmp; ch_tmp = ll.ch.c2; ll.ch.c2 = ll.ch.c3; ll.ch.c3 = ch_tmp; *pl = ll.lo; } /* ** Function to swap short types. */ void swap_short(SHORT *pl) { union myshort { short int lo; struct { char c1, c2; } ch; } ll; char ch_tmp; ll.lo = *pl; ch_tmp = ll.ch.c1; ll.ch.c1 = ll.ch.c2; ll.ch.c2 = ch_tmp; *pl = ll.lo; } ERROR_TYPE swap(IMAGE *im) { unsigned long int i, nbyte; nbyte = GetImNPix(im); /* here we go */ switch (GetImDataType(im)){ case t_USHORT: case t_SHORT: { SHORT *pim; pim = (SHORT *)GetImPtr(im); for (i=0; i. ***********************************************************************/ /* macro definitions for unsigned long int data types */ #define t_PIX_TYPE t_INT32 #define PIX_TYPE INT32 #define BitPerPixel 32 jeolib-miallib-1.1.6/core/c/g32_undef.h000066400000000000000000000017211467232417700175070ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef t_PIX_TYPE #undef PIX_TYPE #undef BitPerPixel jeolib-miallib-1.1.6/core/c/g_def.h000066400000000000000000000015651467232417700170050ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include "uc_def.h" jeolib-miallib-1.1.6/core/c/g_undef.h000066400000000000000000000015671467232417700173520ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include "uc_undef.h" jeolib-miallib-1.1.6/core/c/geodist.c000066400000000000000000000120251467232417700173630ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_dist * @{ */ /* computes a discrete geodesic distance function from a reference set within a geodesic mask. The resulting distance function is overwritten in the geodesic mask. !!! The border of the geodesic mask is set to zero beforehand to avoid border effects */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_geodist(IMAGE *im_m, IMAGE *im_r, long int graph) { /* im_m: geodesic mask (generic type used also for output) */ /* im_r: reference set (unsigned char type) */ /* graph: connectivity */ long int nx, ny, nz, shft[27]; PIX_TYPE *pm, dcrt; UCHAR *pr; long int i, k; FIFO4 *q; int box[6]; if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} generic_framebox(im_m, box, 0); generic_framebox(im_r, box, 0); nx =GetImNx(im_m); ny =GetImNy(im_m); nz =GetImNz(im_m); /* set shift array */ set_seq_shift(nx, ny, nz, graph, shft); q = create_fifo4(nx+ny+nz); if (q == NULL) return ERROR; pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); for (i=nx*ny*nz; i > 0; i--){ *pm ^= (PIX_TYPE)*pr; if (*pm) *pm = PIX_MAX; pm++; pr++; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); for (i=nx*ny*nz; i > 0; i--){ if (*pr){ for (k = 0; k < graph; k++){ if (*(pm + shft[k]) == PIX_MAX){ *(pm + shft[k]) = PIX_MAX - 1; fifo4_add(q, (long int)(pm + shft[k])); } } } pm++; pr++; } dcrt = 0; while (fifo4_empty(q) == 0){ fifo4_add(q, 1L); dcrt++; while ((pm = (PIX_TYPE *)fifo4_remove(q)) != (PIX_TYPE *)1L){ *pm = dcrt; for (k=0; k < graph; ++k){ if (*(pm + shft[k]) == PIX_MAX){ *(pm + shft[k]) = PIX_MAX - 1; fifo4_add(q, (long int)(pm + shft[k])); } } } } free_fifo4(q); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_geodist(IMAGE *im_m, IMAGE *im_r, long int graph) { /* im_m: geodesic mask (generic type used also for output) */ /* im_r: reference set (unsigned char type) */ /* graph: connectivity */ long int nx, ny, nz, shft[27]; PIX_TYPE *pm, dcrt; UCHAR *pr; long int i, k; FIFO4 *q; int box[6]; if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} us_framebox(im_m, box, 0); generic_framebox(im_r, box, 0); nx =GetImNx(im_m); ny =GetImNy(im_m); nz =GetImNz(im_m); /* set shift array */ set_seq_shift(nx, ny, nz, graph, shft); q = create_fifo4(nx+ny+nz); if (q == NULL) return ERROR; pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); for (i=nx*ny*nz; i > 0; i--){ *pm ^= (PIX_TYPE)*pr; if (*pm) *pm = PIX_MAX; pm++; pr++; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); for (i=nx*ny*nz; i > 0; i--){ if (*pr){ for (k = 0; k < graph; k++){ if (*(pm + shft[k]) == PIX_MAX){ *(pm + shft[k]) = PIX_MAX - 1; fifo4_add(q, (long int)(pm + shft[k])); } } } pm++; pr++; } dcrt = 0; while (fifo4_empty(q) == 0){ fifo4_add(q, 1L); dcrt++; while ((pm = (PIX_TYPE *)fifo4_remove(q)) != (PIX_TYPE *)1L){ *pm = dcrt; for (k=0; k < graph; ++k){ if (*(pm + shft[k]) == PIX_MAX){ *(pm + shft[k]) = PIX_MAX - 1; fifo4_add(q, (long int)(pm + shft[k])); } } } } free_fifo4(q); return NO_ERROR; } #include "us_undef.h" ERROR_TYPE geodist(IMAGE *im_m, IMAGE *im_r, int graph) { if (GetImDataType(im_r) != t_UCHAR){ (void)sprintf(buf,"geodist(im_m, im_r, graph): invalid pixel type for im_r (im_r MUST be UCHAR)\n"); errputstr(buf); return ERROR; } switch (GetImDataType(im_m)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_geodist(im_m, im_r, graph)); break; #endif case t_USHORT: return(us_geodist(im_m, im_r, graph)); break; default: (void)sprintf(buf,"geodist(im_m, im_r, graph): invalid pixel type for im_m (valid types are UCHAR or USHORT)\n"); errputstr(buf); return ERROR; } return ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/geom.c000066400000000000000000002263561467232417700166720ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* ** ** Begin: August 30, 2002. */ #include #include #include #include #include "miallib.h" #include "op.h" #if (defined(XLISP)) extern void gc(); #endif /** \defgroup group_geom Image geometry and frames * Functions related to the image geometry. * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" void generic_imcut(IMAGE *imin, IMAGE *imout, int x1, int y1, int z1, int x2, int y2, int z2) { long int nx, ny, nnxb, nnx, nny, nnz, i, j, offset; PIX_TYPE *p, *pi, *po; nx = GetImNx(imin); ny = GetImNy(imin); nnxb = (x2-x1+1)*sizeof(PIX_TYPE); nnx = (x2-x1+1); nny = y2-y1+1; nnz = z2-z1+1; pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); for (i=0; i < nnz; i++){ offset = (z1+i) * nx * ny + x1 + nx * y1; for (j=0; j < nny; j++){ p = pi + offset + nx * j; memcpy((void *)po, (void *)p, nnxb); po += nnx; } } } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" void us_imcut(IMAGE *imin, IMAGE *imout, int x1, int y1, int z1, int x2, int y2, int z2) { long int nx, ny, nnxb, nnx, nny, nnz, i, j, offset; PIX_TYPE *p, *pi, *po; nx = GetImNx(imin); ny = GetImNy(imin); nnxb = (x2-x1+1)*sizeof(PIX_TYPE); nnx = (x2-x1+1); nny = y2-y1+1; nnz = z2-z1+1; pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); for (i=0; i < nnz; i++){ offset = (z1+i) * nx * ny + x1 + nx * y1; for (j=0; j < nny; j++){ p = pi + offset + nx * j; memcpy((void *)po, (void *)p, nnxb); po += nnx; } } } #include "us_undef.h" #include "i32_def.h" void i32_imcut(IMAGE *imin, IMAGE *imout, int x1, int y1, int z1, int x2, int y2, int z2) { long int nx, ny, nnxb, nnx, nny, nnz, i, j, offset; PIX_TYPE *p, *pi, *po; nx = GetImNx(imin); ny = GetImNy(imin); nnxb = (x2-x1+1)*sizeof(PIX_TYPE); nnx = (x2-x1+1); nny = y2-y1+1; nnz = z2-z1+1; pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); for (i=0; i < nnz; i++){ offset = (z1+i) * nx * ny + x1 + nx * y1; for (j=0; j < nny; j++){ p = pi + offset + nx * j; memcpy((void *)po, (void *)p, nnxb); po += nnx; } } } #include "i32_undef.h" /* cut an image */ /* im: pointer to the I/O image */ /* x1 y1 z1: coordinates of the bottom upper left corner of the box */ /* x2 y2 z2: coordinates of the top lower right corner of the box */ IMAGE *imcut(IMAGE *im, int x1, int y1, int z1, int x2, int y2, int z2) { IMAGE *imout; /* check the validity of input parmaters */ if (x1 < 0 || y1 < 0 || z1 < 0 || x2 >= GetImNx(im) || y2 >= GetImNy(im) || z2 >= GetImNz(im) || x2 < x1 || y2 < y1 || z2 < z1){ (void)sprintf(buf, "cut(): invalid parameters\n"); errputstr(buf); return(NULL); } /* create output image */ imout = create_image(GetImDataType(im), x2-x1+1, y2-y1+1, z2-z1+1); if (imout == NULL){ (void)sprintf(buf,"cut(): not enough memory!\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: generic_imcut(im, imout, x1, y1, z1, x2, y2, z2); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: uc_imcut(im, imout, x1, y1, z1, x2, y2, z2); break; #endif case t_SHORT: case t_USHORT: us_imcut(im, imout, x1, y1, z1, x2, y2, z2); break; case t_UINT32: case t_INT32: case t_FLOAT: i32_imcut(im, imout, x1, y1, z1, x2, y2, z2); break; #ifndef NO_d_IMAGE case t_DOUBLE: d_imcut(im, imout, x1, y1, z1, x2, y2, z2); break; #endif default: (void)sprintf(buf,"cut(): invalid pixel type\n"); errputstr(buf); free_image(imout); return(NULL); } return(imout); } #include "uc_def.h" IMAGE *uc_getframebox(IMAGE *im, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; IMAGE *imout; PIX_TYPE *p, *pim, *pout; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "getframebox(): invalid parameters\n"); errputstr(buf); return(NULL); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny, 1, 1); if (imout == NULL){ (void)sprintf(buf,"getframebox(): not enough memory!\n"); errputstr(buf); return(imout); } pout = (PIX_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *pout++ = *p++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *pout++ = *p++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *pout++ = *p++; return imout; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_getframebox(IMAGE *im, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; IMAGE *imout; PIX_TYPE *p, *pim, *pout; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "getframebox(): invalid parameters\n"); errputstr(buf); return(NULL); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny, 1, 1); if (imout == NULL){ (void)sprintf(buf,"getframebox(): not enough memory!\n"); errputstr(buf); return(imout); } pout = (PIX_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *pout++ = *p++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *pout++ = *p++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *pout++ = *p++; return imout; } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_getframebox(IMAGE *im, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; IMAGE *imout; PIX_TYPE *p, *pim, *pout; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "getframebox(): invalid parameters\n"); errputstr(buf); return(NULL); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny, 1, 1); if (imout == NULL){ (void)sprintf(buf,"getframebox(): not enough memory!\n"); errputstr(buf); return(imout); } pout = (PIX_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *pout++ = *p++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *pout++ = *p++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *pout++ = *p++; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *pout++ = *p++; return imout; } #include "i32_undef.h" IMAGE *getframebox(IMAGE *im, int *box) { if ( (box[0]+box[1]+box[2]+box[3]+box[4]+box[5]) == 0) return NULL; switch (GetImDataType(im)){ case t_UCHAR: return(uc_getframebox(im, box)); break; case t_USHORT: return(us_getframebox(im, box)); break; case t_INT32: return(i32_getframebox(im, box)); break; default: (void) sprintf(buf, "getframebox(): invalid pixel type\n"); errputstr(buf); return NULL; } return NULL; } #include "uc_def.h" ERROR_TYPE uc_setframebox(IMAGE *im, IMAGE *imframe, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim, *pframe; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "setframebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* check size of imframe */ if ( GetImNx(imframe) != (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny ){ (void)sprintf(buf,"setframebox(): frame image not matching border geometry (box)!\n"); errputstr(buf); return(ERROR); } pframe = (PIX_TYPE *)GetImPtr(imframe); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = *pframe++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = *pframe++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = *pframe++;; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = *pframe++; return NO_ERROR; } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_setframebox(IMAGE *im, IMAGE *imframe, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim, *pframe; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "setframebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* check size of imframe */ if ( GetImNx(imframe) != (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny ){ (void)sprintf(buf,"setframebox(): frame image not matching border geometry (box)!\n"); errputstr(buf); return(ERROR); } pframe = (PIX_TYPE *)GetImPtr(imframe); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = *pframe++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = *pframe++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = *pframe++;; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = *pframe++; return NO_ERROR; } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_setframebox(IMAGE *im, IMAGE *imframe, int *box) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim, *pframe; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "setframebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); /* check size of imframe */ if ( GetImNx(imframe) != (box[0]+box[1])*ny*nz + (box[2]+box[3])*nx*nz + (box[4]+box[5])*nx*ny ){ (void)sprintf(buf,"setframebox(): frame image not matching border geometry (box)!\n"); errputstr(buf); return(ERROR); } pframe = (PIX_TYPE *)GetImPtr(imframe); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = *pframe++; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = *pframe++; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = *pframe++; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = *pframe++;; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = *pframe++; return NO_ERROR; } #include "i32_undef.h" ERROR_TYPE setframebox(IMAGE *im, IMAGE *im_frame, int *box) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_setframebox(im, im_frame, box)); break; case t_USHORT: return(us_setframebox(im, im_frame, box)); break; case t_INT32: return(i32_setframebox(im, im_frame, box)); break; default: (void) sprintf(buf, "setframebox(): invalid pixel type\n"); errputstr(buf); return ERROR; } return ERROR; } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "u32_def.h" ERROR_TYPE u32_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "u32_undef.h" #include "uc_def.h" ERROR_TYPE uc_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "uc_undef.h" #include "i32_def.h" ERROR_TYPE i32_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "i32_undef.h" #include "us_def.h" ERROR_TYPE us_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "us_undef.h" #include "f_def.h" ERROR_TYPE f_framebox(IMAGE *im, int *box, PIX_TYPE val) { long int nx, ny, nz; long int x, y, z, l1, l2; PIX_TYPE *p, *pim; /* check the validity of input parmaters */ if (box[0] > GetImNx(im) || box[1] > GetImNx(im) || box[2] > GetImNy(im) || box[3] > GetImNy(im) || box[4] > GetImNz(im) || box[5] > GetImNz(im)){ (void)sprintf(buf, "framebox(): invalid parameters\n"); errputstr(buf); return(ERROR); } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); pim = (PIX_TYPE *)GetImPtr(im); l1 = box[0]; l2 = box[1]; /* left and right borders */ for (z = 0; z < nz; z++){ for (y = 0; y < ny; y++){ p = pim + z * nx * ny + y * nx; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + y * nx + nx - l2; for (x = 0; x < l2; x++) *p++ = val; } } l1 = box[2] * nx; l2 = box[3] * nx; /* top and bottom borders */ for (z = 0; z < nz; z++){ p = pim + z * nx * ny; for (x = 0; x < l1; x++) *p++ = val; p = pim + z * nx * ny + nx * (ny - box[3]); for (x = 0; x < l2; x++) *p++ = val; } l1 = box[4] * nx * ny; l2 = box[5] * nx * ny; /* up and down borders */ p = pim; for (x = 0; x < l1; x++) *p++ = val; p = pim + nx * ny * (nz - box[5]); for (x = 0; x < l2; x++) *p++ = val; return NO_ERROR; } #include "f_undef.h" /* overwrite a frame of arbitrary shape around an image */ /* im: pointer to the I/O image */ /* box: array of 6 elements for the shape of the frame */ /* val: value of the frame to be overwritten */ ERROR_TYPE framebox(IMAGE *im, int *box, G_TYPE gval) { switch (GetImDataType(im)){ #ifdef NO_generic_IMAGE case t_GENERIC: return(generic_framebox(im, box, gval.generic_val)); break; #endif case t_UCHAR: return(uc_framebox(im, box, gval.uc_val)); break; case t_USHORT: return(us_framebox(im, box, gval.us_val)); break; case t_INT32: return(i32_framebox(im, box, gval.i32_val)); break; case t_UINT32: return(u32_framebox(im, box, gval.u32_val)); break; case t_FLOAT: return(f_framebox(im, box, gval.f_val)); break; default: (void) sprintf(buf, "framebox(): invalid pixel type\n"); errputstr(buf); return ERROR; } return NO_ERROR; } #include "us_def.h" ERROR_TYPE us_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #ifdef XLISP gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "us_undef.h" #include "s_def.h" ERROR_TYPE s_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #ifdef XLISP gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "s_undef.h" #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #if (defined(XLISP)) gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "i32_def.h" ERROR_TYPE i32_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #if (defined(XLISP)) gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "i32_undef.h" #include "u32_def.h" ERROR_TYPE u32_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #if (defined(XLISP)) gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "u32_undef.h" #include "f_def.h" ERROR_TYPE f_addframebox(IMAGE *im, int *box, PIX_TYPE val) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z, l1, l2; PIX_TYPE *pi, *po, *pim; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi + box[0] + box[1]; nyo = nyi + box[2] + box[3]; nzo = nzi + box[4] + box[5]; nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ #if (defined(XLISP)) gc(); pim = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (pim == NULL){ (void)sprintf(buf,"ERROR: addframebox: realloc returns a void pointer\n"); errputstr(buf); return ERROR; } #else (void) sprintf(buf,"addframebox(): not enough memory.\n"); errputstr(buf); return ERROR; #endif } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, pim); SetImNByte(im, nbyte); l2 = box[5] * nxo * nyo; /* up border */ po = pim + nxo * nyo * (nzo - box[5]); for (x = 0; x < l2; x++) *po++ = val; pi = pim + nxi * nyi * nzi - 1; po = pim + (nzo - box[5]) * nxo * nyo - 1; for (z = 0; z < nzi; z++){ l2 = box[3] * nxo; for (x = 0; x < l2; x++) /* bottom border */ *po-- = val; l1 = box[0]; l2 = box[1]; for (y = 0; y < nyi; y++){ for (x = 0; x < l2; x++) /* right border */ *po-- = val; for (x = 0; x < nxi; x++) *po-- = *pi--; for (x = 0; x < l1; x++) /* left border */ *po-- = val; } l1 = box[2] * nxo; /* top border */ for (x = 0; x < l1; x++) *po-- = val; } l1 = box[4] * nxo * nyo; /* down border */ for (x = 0; x < l1; x++) *po-- = val; return NO_ERROR; } #include "f_undef.h" /* add a border around an image */ /* im: pointer to the I/O image */ /* box: array of 6 elements for the shape of the border */ /* val: value of the added border */ ERROR_TYPE addframebox(IMAGE *im, int *box, G_TYPE gval) { if ( (box[0]+box[1]+box[2]+box[3]+box[4]+box[5]) == 0) return NO_ERROR; switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_addframebox(im, box, gval.generic_val)); break; #endif case t_USHORT: return(us_addframebox(im, box, gval.us_val)); break; case t_SHORT: return(s_addframebox(im, box, gval.s_val)); break; case t_UINT32: return(u32_addframebox(im, box, gval.u32_val)); break; case t_INT32: return(i32_addframebox(im, box, gval.i32_val)); break; case t_FLOAT: return(f_addframebox(im, box, gval.f_val)); break; default: (void) sprintf(buf, "addframebox(): invalid pixel type\n"); errputstr(buf); return ERROR; } return NO_ERROR; } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_subframebox(IMAGE *im, int *box) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z; PIX_TYPE *pi, *po; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi - box[0] - box[1]; nyo = nyi - box[2] - box[3]; nzo = nzi - box[4] - box[5]; pi = (PIX_TYPE *)GetImPtr(im) + nxi * nyi * box[4]; po = (PIX_TYPE *)GetImPtr(im); for (z = 0; z < nzo; z++){ pi += box[2] * nxi; for (y = 0; y < nyo; y++){ pi += box[0]; for (x = 0; x < nxo; x++) *po++ = *pi++; pi += box[1]; } pi += box[3] * nxi; } nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); po = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (po == NULL){ (void) sprintf(buf, "subframebox(): Realloc unsuccessful!!! Image modified\n"); errputstr(buf); return ERROR; } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, po); SetImNByte(im, nbyte); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "i32_def.h" ERROR_TYPE i32_subframebox(IMAGE *im, int *box) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z; PIX_TYPE *pi, *po; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi - box[0] - box[1]; nyo = nyi - box[2] - box[3]; nzo = nzi - box[4] - box[5]; pi = (PIX_TYPE *)GetImPtr(im) + nxi * nyi * box[4]; po = (PIX_TYPE *)GetImPtr(im); for (z = 0; z < nzo; z++){ pi += box[2] * nxi; for (y = 0; y < nyo; y++){ pi += box[0]; for (x = 0; x < nxo; x++) *po++ = *pi++; pi += box[1]; } pi += box[3] * nxi; } nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); po = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (po == NULL){ (void) sprintf(buf, "subframebox(): Realloc unsuccessful!!! Image modified\n"); errputstr(buf); return ERROR; } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, po); SetImNByte(im, nbyte); return NO_ERROR; } #include "i32_undef.h" #include "us_def.h" ERROR_TYPE us_subframebox(IMAGE *im, int *box) { unsigned long int nbyte; long int nxi, nyi, nzi; long int nxo, nyo, nzo; long int x, y, z; PIX_TYPE *pi, *po; nxi = GetImNx(im); nyi = GetImNy(im); nzi = GetImNz(im); nxo = nxi - box[0] - box[1]; nyo = nyi - box[2] - box[3]; nzo = nzi - box[4] - box[5]; pi = (PIX_TYPE *)GetImPtr(im) + nxi * nyi * box[4]; po = (PIX_TYPE *)GetImPtr(im); for (z = 0; z < nzo; z++){ pi += box[2] * nxi; for (y = 0; y < nyo; y++){ pi += box[0]; for (x = 0; x < nxo; x++) *po++ = *pi++; pi += box[1]; } pi += box[3] * nxi; } nbyte=nxo*nyo*nzo*sizeof(PIX_TYPE); if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); po = (PIX_TYPE *)realloc((char *)GetImPtr(im), nbyte); if (po == NULL){ (void) sprintf(buf, "subframebox(): Realloc unsuccessful!!! Image modified\n"); errputstr(buf); return ERROR; } SetImNx(im, nxo); SetImNy(im, nyo); SetImNz(im, nzo); SetImPtr(im, po); SetImNByte(im, nbyte); return NO_ERROR; } #include "us_undef.h" ERROR_TYPE subframebox(IMAGE *im, int *box) { if ( (box[0]+box[1]+box[2]+box[3]+box[4]+box[5]) == 0) return NO_ERROR; switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_subframebox(im, box)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_subframebox(im, box)); break; #endif case t_SHORT: case t_USHORT: return(us_subframebox(im, box)); break; case t_FLOAT: /* POTENTIAL BUG: assumes that sizeof(float) is equal to sizeof(long int) */ case t_UINT32: case t_INT32: return(i32_subframebox(im, box)); break; default: (void) sprintf(buf, "subframebox(): invalid pixel type\n"); errputstr(buf); return ERROR; } return NO_ERROR; } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; long int test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ case AND_op: #if (FLOATING==0) for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; #endif case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; long int test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ case AND_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "us_undef.h" #include "s_def.h" ERROR_TYPE s_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; long int test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ case AND_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "s_undef.h" #include "f_def.h" ERROR_TYPE f_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; float test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ #if (FLOATING==0) case AND_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; #endif case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "f_undef.h" #include "i32_def.h" ERROR_TYPE i32_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; long int test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ case AND_op: #if (FLOATING==0) for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; #endif case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "i32_undef.h" #include "u32_def.h" ERROR_TYPE u32_imputop(IMAGE *imout, IMAGE *imin, int x1, int y1, int z1, int op) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; long int test; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); switch(op){ case AND_op: #if (FLOATING==0) for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p&=*pi; } } } break; case OR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p|=*pi; } } } break; case XOR_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p^=*pi; } } } break; #endif case ADD_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p+*pi; if (test > PIX_MAX){ *p = PIX_MAX; } else *p=(PIX_TYPE) test; } } } break; case SUB_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ test = *p-*pi; if (test < PIX_MIN){ *p = PIX_MIN; } else *p=(PIX_TYPE) test; } } } break; case ADD_op_ovfl: /* do not check for overflows */ for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p+=*pi; } } } break; case INF_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p>*pi) *p = *pi; } } } break; case SUP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p<*pi) *p = *pi; } } } break; case OVW_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p = *pi; } } } break; case MASK_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*pi!=0) *p = *pi; } } } break; case MASK_op2: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p==0) *p = *pi; } } } break; case MULT_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ *p *= *pi; } } } break; case CMP_op: for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++){ if (*p < *pi) *p = 1; else if (*p > *pi) *p = 2; else *p = 0; } } } break; default: (void)sprintf(buf, "ERROR in inmputop(): \ invalid op value\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "u32_undef.h" ERROR_TYPE imputop(IMAGE *im1, IMAGE *im2, int x, int y, int z, int op) { /* check that im2 is a subset of im1 given x, y, and z */ if (GetImNx(im2)>GetImNx(im1)-x || GetImNy(im2)>GetImNy(im1)-y || \ GetImNz(im2)>GetImNz(im1)-z || (GetImDataType(im2)!=GetImDataType(im1) )){ iminfo(im1); iminfo(im2); (void)sprintf(buf, "imputop(im1.type=%d, im2.type=%d, %d, %d, %d, %d): invalid parameters or image size or types (input images must have the same type)\n", GetImDataType(im1), GetImDataType(im2), x, y, z, op); errputstr(buf); return(ERROR); } switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_imputop(im1, im2, x, y, z, op)); break; #endif case t_SHORT: return(s_imputop(im1, im2, x, y, z, op)); break; case t_USHORT: return(us_imputop(im1, im2, x, y, z, op)); break; case t_FLOAT: return(f_imputop(im1, im2, x, y, z, op)); break; case t_INT32: return(i32_imputop(im1, im2, x, y, z, op)); break; case t_UINT32: return(u32_imputop(im1, im2, x, y, z, op)); break; default: (void)sprintf(buf,"imputop()op: invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" #define PIX_IMLBL_TYPE unsigned char ERROR_TYPE uc_uc_imputcompose(IMAGE *imin, IMAGE *imlbl, IMAGE *imout, int x1, int y1, int z1, int val) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; PIX_IMLBL_TYPE *plbl, *plbl0; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); plbl0 = (PIX_IMLBL_TYPE *)GetImPtr(imlbl); for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; plbl = plbl0 + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++,plbl++){ if(*plbl==val) *p=*pi; } } } return(NO_ERROR); } #undef PIX_IMLBL_TYPE #include "uc_undef.h" #include "uc_def.h" #define PIX_IMLBL_TYPE unsigned short ERROR_TYPE us_uc_imputcompose(IMAGE *imin, IMAGE *imlbl, IMAGE *imout, int x1, int y1, int z1, int val) { /* we assume that imin is smaller than imout in all directions */ int nx, ny, nz, i, j, k; PIX_TYPE *p, *pi, *po; PIX_IMLBL_TYPE *plbl, *plbl0; nx = GetImNx(imin); ny = GetImNy(imin); nz = GetImNz(imin); pi = (PIX_TYPE *)GetImPtr(imin); po = (PIX_TYPE *)GetImPtr(imout); plbl0 = (PIX_IMLBL_TYPE *)GetImPtr(imlbl); for (i=0; i < nz; i++){ for (j=0; j < ny; j++){ p = po + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; plbl = plbl0 + (z1+i) * GetImNx(imout)*GetImNy(imout) + GetImNx(imout)*(y1+j) + x1; for (k=0; k < nx; k++,pi++,p++,plbl++){ if(*plbl==val) *p=*pi; } } } return(NO_ERROR); } #undef PIX_IMLBL_TYPE #include "uc_undef.h" ERROR_TYPE imputcompose(IMAGE *im1, IMAGE *imlbl, IMAGE *im2, int x, int y, int z, int val) { /* check that im1 is a subset of im2 given x, y, and z */ if (GetImNx(im1)>GetImNx(im2)-x || GetImNy(im1)>GetImNy(im2)-y || GetImNz(im1)>GetImNz(im2)-z || (GetImDataType(im1)!=GetImDataType(im2) )){ (void)sprintf(buf, "imput(): invalid parameters or image size or types (input images must have the same type)\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(im1)){ case t_UCHAR: switch (GetImDataType(imlbl)){ case t_UCHAR: return(uc_uc_imputcompose(im1, imlbl, im2, x, y, z, val)); break; break; case t_USHORT: return(us_uc_imputcompose(im1, imlbl, im2, x, y, z, val)); break; default: (void)sprintf(buf,"imputcompose(): invalid pixel type for label image\n"); errputstr(buf); return(ERROR); } default: (void)sprintf(buf,"imputcompose(): invalid pixel type for 1st image\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" IMAGE *uc_getboundingbox(IMAGE *im) { IMAGE *bb_im; PIX_TYPE *pim; INT32 *pbb, ulcx=GetImNx(im), ulcy=GetImNy(im), lrcx=0, lrcy=0; int x,y,nx=GetImNx(im),ny=GetImNy(im); bb_im=create_image(t_INT32, 4, 1, 1); pbb=(INT32 *)GetImPtr(bb_im); pim=(PIX_TYPE *)GetImPtr(im); for (y=0;ylrcx) lrcx=x; if (ylrcy) lrcy=y; } } } pbb[0]=ulcx; pbb[1]=ulcy; pbb[2]=lrcx; pbb[3]=lrcy; return bb_im; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_getboundingbox(IMAGE *im) { IMAGE *bb_im; PIX_TYPE *pim; INT32 *pbb, ulcx=GetImNx(im), ulcy=GetImNy(im), lrcx=0, lrcy=0; int x,y,nx=GetImNx(im),ny=GetImNy(im); bb_im=create_image(t_INT32, 4, 1, 1); pbb=(INT32 *)GetImPtr(bb_im); pim=(PIX_TYPE *)GetImPtr(im); for (y=0;ylrcx) lrcx=x; if (ylrcy) lrcy=y; } } } pbb[0]=ulcx; pbb[1]=ulcy; pbb[2]=lrcx; pbb[3]=lrcy; return bb_im; } #include "us_undef.h" #include "f_def.h" IMAGE *f_getboundingbox(IMAGE *im) { IMAGE *bb_im; PIX_TYPE *pim; INT32 *pbb, ulcx=GetImNx(im), ulcy=GetImNy(im), lrcx=0, lrcy=0; int x,y,nx=GetImNx(im),ny=GetImNy(im); bb_im=create_image(t_INT32, 4, 1, 1); pbb=(INT32 *)GetImPtr(bb_im); pim=(PIX_TYPE *)GetImPtr(im); for (y=0;ylrcx) lrcx=x; if (ylrcy) lrcy=y; } } } pbb[0]=ulcx; pbb[1]=ulcy; pbb[2]=lrcx; pbb[3]=lrcy; return bb_im; } #include "f_undef.h" IMAGE *getboundingbox(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_getboundingbox(im)); break; case t_USHORT: return(us_getboundingbox(im)); break; case t_FLOAT: return(f_getboundingbox(im)); break; default: (void)sprintf(buf,"getboundingbox(im): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } #include "uc_def.h" IMAGE *uc_magnify(IMAGE *im, int n) { IMAGE *imout; PIX_TYPE *p, *pout; int nx=GetImNx(im); int ny=GetImNy(im); int x, y, i, j; imout=(IMAGE *)create_image(t_PIX_TYPE, n*nx, n*ny, 1); if (imout==NULL){ return NULL; } p=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); for (y=0;y 1){ (void)sprintf(buf,"magnify(im, n): input image im must be 2-D\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im)){ case t_UCHAR: return(uc_magnify(im, n)); break; case t_USHORT: return(us_magnify(im, n)); break; case t_UINT32: case t_MIALFLOAT: return(u32_magnify(im, n)); break; default: (void)sprintf(buf,"magnify(im, n): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } #define rotate_x(x, y, sint, cost) ((cost * x) + (sint * y)) #define rotate_y(x, y, sint, cost) ((cost * y) - (sint * x)) #include "uc_def.h" IMAGE **uc_rotatecoor(IMAGE *im, double theta) { IMAGE *imx, *imy, **imout; MIALFLOAT *pimx, *pimy; int nx=GetImNx(im); int ny=GetImNy(im); int x, y, xc, yc, nxp, nyp; double cost=cos(theta), sint=sin(theta); double urc_x, llc_x, lrc_x, urc_y, llc_y, lrc_y; double xmin, xmax, ymin, ymax; urc_x=rotate_x(nx, 0, sint, cost); urc_y=rotate_y(nx, 0, sint, cost); llc_x=rotate_x(0, ny, sint, cost); llc_y=rotate_y(0, ny, sint, cost); lrc_x=rotate_x(nx, ny,sint, cost); lrc_y=rotate_y(nx, ny,sint, cost); xmin=MIN(0.0,MIN(urc_x,MIN(llc_x,lrc_x))); xmax=MAX(0.0,MAX(urc_x,MAX(llc_x,lrc_x))); ymin=MIN(0.0,MIN(urc_y,MIN(llc_y,lrc_y))); ymax=MAX(0.0,MAX(urc_y,MAX(llc_x,lrc_y))); nxp=(int)round(abs(xmax-xmin))+1; nyp=(int)round(abs(ymax-ymin))+1; imout=(IMAGE **)calloc(sizeof(IMAGE *), 2); imx=create_image(t_FLOAT, nxp, nyp, 1); if (imx==NULL) return NULL; imy=create_image(t_FLOAT, nxp, nyp, 1); if (imy==NULL){ free_image(imx); return NULL; } f_blank(imx, -100.0); f_blank(imy, -100.0); pimx=(MIALFLOAT *)GetImPtr(imx); pimy=(MIALFLOAT *)GetImPtr(imy); // printf("xmin=%d xmax=%d ymin=%d ymax=%d", (int)xmin, (int)xmax, (int)ymin, (int)ymax); for (x=floor(xmin),xc=0; x<=xmax; x++, xc++){ for (y=floor(ymin),yc=0; y<=ymax; y++, yc++){ // printf("rotate_x(%d,%d,-sint,cost)=%f\n", x, y, (float)rotate_x(x,y,-sint,cost)); *(pimx+xc+yc*nxp)=(float)rotate_x(x,y,-sint,cost); *(pimy+xc+yc*nxp)=(float)rotate_y(x,y,-sint,cost); } } imout[0]=imx; imout[1]=imy; return imout; } #include "uc_undef.h" #include "us_def.h" IMAGE **us_rotatecoor(IMAGE *im, double theta) { IMAGE *imx, *imy, **imout; MIALFLOAT *pimx, *pimy; int nx=GetImNx(im); int ny=GetImNy(im); int x, y, xc, yc, nxp, nyp; double cost=cos(theta), sint=sin(theta); double urc_x, llc_x, lrc_x, urc_y, llc_y, lrc_y; double xmin, xmax, ymin, ymax; urc_x=rotate_x(nx, 0, sint, cost); urc_y=rotate_y(nx, 0, sint, cost); llc_x=rotate_x(0, ny, sint, cost); llc_y=rotate_y(0, ny, sint, cost); lrc_x=rotate_x(nx, ny,sint, cost); lrc_y=rotate_y(nx, ny,sint, cost); xmin=MIN(0.0,MIN(urc_x,MIN(llc_x,lrc_x))); xmax=MAX(0.0,MAX(urc_x,MAX(llc_x,lrc_x))); ymin=MIN(0.0,MIN(urc_y,MIN(llc_y,lrc_y))); ymax=MAX(0.0,MAX(urc_y,MAX(llc_x,lrc_y))); nxp=(int)round(abs(xmax-xmin))+1; nyp=(int)round(abs(ymax-ymin))+1; imout=(IMAGE **)calloc(sizeof(IMAGE *), 2); imx=create_image(t_FLOAT, nxp, nyp, 1); if (imx==NULL) return NULL; imy=create_image(t_FLOAT, nxp, nyp, 1); if (imy==NULL){ free_image(imx); return NULL; } f_blank(imx, -100.0); f_blank(imy, -100.0); pimx=(MIALFLOAT *)GetImPtr(imx); pimy=(MIALFLOAT *)GetImPtr(imy); // printf("xmin=%d xmax=%d ymin=%d ymax=%d", (int)xmin, (int)xmax, (int)ymin, (int)ymax); for (x=floor(xmin),xc=0; x<=xmax; x++, xc++){ for (y=floor(ymin),yc=0; y<=ymax; y++, yc++){ // printf("rotate_x(%d,%d,-sint,cost)=%f\n", x, y, (float)rotate_x(x,y,-sint,cost)); *(pimx+xc+yc*nxp)=(float)rotate_x(x,y,-sint,cost); *(pimy+xc+yc*nxp)=(float)rotate_y(x,y,-sint,cost); } } imout[0]=imx; imout[1]=imy; return imout; } #include "us_undef.h" IMAGE **rotatecoor(IMAGE *im, double theta) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_rotatecoor(im, theta)); break; case t_USHORT: return(uc_rotatecoor(im, theta)); break; default: (void)sprintf(buf,"rotatecoor(im, theta): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } /** @}*/ jeolib-miallib-1.1.6/core/c/ggeo.c000066400000000000000000000563631467232417700166630ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file skel.c * @author Pierre Soille * @date * * @details see also \cite soille94 * */ /* ** INT32 sqtgg(im_m, im_r, graph) ** INT32 sqdgg(im_m, im_r, graph) ** INT32 sqizgg(im_m, im_r, graph) ** INT32 sqdir(im_m, im_r, graph) */ #include #include #include #include "miallib.h" #include "fah.h" #include "pqueue.h" #if (defined(XLISP)) extern void gc(); #endif extern void emergencyfree_pq(struct pqueue *); /** \addtogroup group_dist * @{ */ /* ** Function to compute the geodesic TIME function. ** The results are overwritten in the geodesic mask. */ #include "uc_def.h" #define PR_MAX (PIX_MAX/2) #define MSK 3 /* pixels having this value in reference image will not be further processed */ #define INQUEUE 4 /* pixels having this value in reference image will not be further processed */ #define UNREACHEDVAL 0 ERROR_TYPE uc_sqtg(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of numerical geodesic mask I (CHAR) & O(INT32) ** im_r : image of reference set I (CHAR) ** graph: type of graph (2d || 3d) */ FIFO *pf; FIFO **fifo; unsigned long int i; int k, t; PIX_TYPE *pm, *p_k, pr_max; UCHAR *pr; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} pr_max = PR_MAX; if (GetImDataType(im_m) != t_UCHAR){ (void) sprintf(buf, "sqtgg(): input images must be of type CHAR\n"); errputstr(buf); return ERROR; } if (szgeocompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtgg(): input images must be of same geometry\n"); errputstr(buf); return ERROR; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return ERROR; } /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR) return ERROR; if (generic_framebox(im_r, box, MSK) == ERROR) return(ERROR); if (generic_framebox(im_m, box, PIX_MSB) == ERROR) return(ERROR); /* Initialize the FAH */ LOOPDN(i, GetImNPix(im_m)){ if (*pr == 1){ for (k = 0; k < graph; ++k){ if (*(pr + shift[k]) == 0){ p_k = pm + shift[k]; if (*p_k > pr_max) *p_k=pr_max; else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(GetImNx(im_m)); } fifo_add(fifo[*p_k], (long int)p_k); *(pr + shift[k]) = INQUEUE; *p_k |= PIX_MSB; } } *pr=2; *pm=PIX_MSB; } else if (*pr == MSK) /* 2 -> will not be further processed */ *pm = PIX_MSB; pr++; pm++; } /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shift[k]; if (*p_k & PIX_MSB) continue; *p_k += t; if (*p_k > pr_max) *p_k=pr_max; if (fifo[*p_k] == NULL) fifo[*p_k] = alloc_fifo(GetImNx(im_m)); fifo_add(fifo[*p_k], (long int)p_k); *p_k |= PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); LOOPDN(i, GetImNPix(im_m)){ if ( ((*pm & PIX_MSB) == 0) || (*pr==MSK) ) *pm=UNREACHEDVAL; else *pm ^= PIX_MSB; pm++; if(*pr==INQUEUE) *pr=0; else *pr=1; pr++; } return NO_ERROR; } #include "uc_undef.h" #undef PR_MAX #undef MSK #undef INQUEUE #undef UNREACHEDVAL #include "us_def.h" #define PR_MAX (PIX_MAX/2) #define MSK 3 /* pixels having this value in reference image will not be further processed */ #define INQUEUE 4 /* pixels having this value in reference image will not be further processed */ #define UNREACHEDVAL 0 ERROR_TYPE us_sqtg(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of numerical geodesic mask I (CHAR) & O(INT32) ** im_r : image of reference set I (CHAR) ** graph: type of graph (2d || 3d) */ FIFO *pf; FIFO **fifo; unsigned long int i; int k, t; PIX_TYPE *pm, *p_k, pr_max; UCHAR *pr; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} pr_max = PR_MAX; if (GetImDataType(im_m) != t_USHORT){ (void) sprintf(buf, "sqtgg(): input images must be of type CHAR\n"); errputstr(buf); return ERROR; } if (szgeocompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtgg(): input images must be of same geometry\n"); errputstr(buf); return ERROR; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return ERROR; } /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR) return ERROR; if (generic_framebox(im_r, box, MSK) == ERROR) return(ERROR); if (us_framebox(im_m, box, PIX_MSB) == ERROR) return(ERROR); /* Initialize the FAH */ LOOPDN(i, GetImNPix(im_m)){ if (*pr == 1){ for (k = 0; k < graph; ++k){ if (*(pr + shift[k]) == 0){ p_k = pm + shift[k]; if (*p_k > pr_max) *p_k=pr_max; else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(GetImNx(im_m)); } fifo_add(fifo[*p_k], (long int)p_k); *(pr + shift[k]) = INQUEUE; *p_k |= PIX_MSB; } } *pr=2; *pm=PIX_MSB; } else if (*pr == MSK) /* 2 -> will not be further processed */ *pm = PIX_MSB; pr++; pm++; } /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shift[k]; if (*p_k & PIX_MSB) continue; *p_k += t; if (*p_k > pr_max) *p_k=pr_max; if (fifo[*p_k] == NULL) fifo[*p_k] = alloc_fifo(GetImNx(im_m)); fifo_add(fifo[*p_k], (long int)p_k); *p_k |= PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); LOOPDN(i, GetImNPix(im_m)){ if ( ((*pm & PIX_MSB) == 0) || (*pr==MSK) ) *pm=UNREACHEDVAL; else *pm ^= PIX_MSB; pm++; if(*pr==INQUEUE) *pr=0; else *pr=1; pr++; } return NO_ERROR; } #include "us_undef.h" #undef PR_MAX #undef MSK #undef INQUEUE #undef UNREACHEDVAL #include "u32_def.h" #define PR_MAX 262140 // GLOUP SHOULD BE (PIX_MAX/2) USE pq instead #define MSK 3 /* pixels having this value in reference image will not be further processed */ #define INQUEUE 4 /* pixels having this value in reference image will not be further processed */ #define UNREACHEDVAL 0 ERROR_TYPE u32_sqtg(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of numerical geodesic mask I (CHAR) & O(INT32) ** im_r : image of reference set I (CHAR) ** graph: type of graph (2d || 3d) */ FIFO *pf; FIFO **fifo; unsigned long int i; int k, t; PIX_TYPE *pm, *p_k, pr_max; UCHAR *pr; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} pr_max = PR_MAX; if (GetImDataType(im_m) != t_INT32){ (void) sprintf(buf, "sqtgg(): input images must be of type CHAR\n"); errputstr(buf); return ERROR; } if (szgeocompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtgg(): input images must be of same geometry\n"); errputstr(buf); return ERROR; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return ERROR; } /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR) return ERROR; if (generic_framebox(im_r, box, MSK) == ERROR) return(ERROR); if (u32_framebox(im_m, box, PIX_MSB) == ERROR) return(ERROR); /* Initialize the FAH */ LOOPDN(i, GetImNPix(im_m)){ if (*pr == 1){ for (k = 0; k < graph; ++k){ if (*(pr + shift[k]) == 0){ p_k = pm + shift[k]; if (*p_k > pr_max) *p_k=pr_max; else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(GetImNx(im_m)); } fifo_add(fifo[*p_k], (long int)p_k); *(pr + shift[k]) = INQUEUE; *p_k |= PIX_MSB; } } *pr=2; *pm=PIX_MSB; } else if (*pr == MSK) /* 2 -> will not be further processed */ *pm = PIX_MSB; pr++; pm++; } /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shift[k]; if (*p_k & PIX_MSB) continue; *p_k += t; if (*p_k > pr_max) *p_k=pr_max; if (fifo[*p_k] == NULL) fifo[*p_k] = alloc_fifo(GetImNx(im_m)); fifo_add(fifo[*p_k], (long int)p_k); *p_k |= PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); LOOPDN(i, GetImNPix(im_m)){ if ( ((*pm & PIX_MSB) == 0) || (*pr==MSK) ) *pm=UNREACHEDVAL; else *pm ^= PIX_MSB; pm++; if(*pr==INQUEUE) *pr=0; else *pr=1; pr++; } return NO_ERROR; } #include "u32_undef.h" #undef PR_MAX #undef MSK #undef INQUEUE #undef UNREACHEDVAL ERROR_TYPE sqtg_old(IMAGE *im_m, IMAGE *im_r, int graph) { switch (GetImDataType(im_m)){ case t_UCHAR: uc_sqtg(im_m, im_r, graph); break; case t_USHORT: us_sqtg(im_m, im_r, graph); break; case t_INT32: /* but call unsigned long int */ u32_sqtg(im_m, im_r, graph); break; default: (void)sprintf(buf, "ERROR in sqtg(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "i32_def.h" #define PR_MAX 32767 #define MSK 65534 /* pixels having this value in reference image will not be further processed */ #define REF_TYPE USHORT #define REF_PIX_MSB 0x8000 /* 32768 */ ERROR_TYPE i32_sqtgpla(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of numerical geodesic mask I (INT32) ** im_r : image of `reference set' I (SHORT) Actual references with MSB set and grey values for plateau in which the propagation should occur. ** graph: type of graph (2d || 3d) */ register FIFO *pf; FIFO **fifo, **fifot; INT32 i, k, t; PIX_TYPE *pm, *p_k; REF_TYPE *pr, valpla; INT32 pr_max; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} pr_max = PR_MAX; if (GetImDataType(im_m) != t_INT32){ (void) sprintf(buf, "sqtggpla(): input images must be of type CHAR\n"); errputstr(buf); return ERROR; } if (GetImDataType(im_r) != t_USHORT){ (void) sprintf(buf, "sqtggpla(): input images must be of type USHORT\n"); errputstr(buf); return ERROR; } if (szgeocompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtggpla(): input images must be of same type\n"); errputstr(buf); return ERROR; } pm = (PIX_TYPE *)GetImPtr(im_m); /* mask */ pr = (REF_TYPE *)GetImPtr(im_r); /* marker */ /* Create an array of FIFO */ if ((fifo = (FIFO **)calloc(PR_MAX + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return ERROR; } /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR) return ERROR; if (us_framebox(im_r, box, MSK) == ERROR) return(ERROR); if (i32_framebox(im_m, box, REF_PIX_MSB) == ERROR) return(ERROR); /* Initialize the FAH */ LOOPDN(i, GetImNPix(im_m)){ if (*pr & REF_PIX_MSB){ valpla = *pr ^ REF_PIX_MSB; if (valpla !=0){ for (k = 0; k < graph; ++k){ if (*(pr + shift[k]) == valpla){ p_k = pm + shift[k]; if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return -9; } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(GetImNx(im_m)); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(GetImNx(im_m)); } fifo_add(fifo[*p_k], (long int)p_k); *(pr + shift[k]) = MSK; *p_k |= REF_PIX_MSB; } } } *pr=2; *pm=REF_PIX_MSB; } else if (*pr == 0) /* 2 -> will not be further processed */ *pm = REF_PIX_MSB; pr++; pm++; } /* Ordered propagation of geodesic time function */ for (t = 0; t <= pr_max; t++){ pf = fifo[t]; if (pf != NULL){ while (fifo_empty(pf) == FALSE){ pm = (PIX_TYPE *)fifo_remove(pf); for (k = 0; k < graph; ++k){ p_k = pm + shift[k]; if (*p_k & REF_PIX_MSB) continue; *p_k += t; if (*p_k > pr_max){ if ((fifot = (FIFO **)calloc(*p_k + 1, sizeof(FIFO *))) == NULL){ (void) printf("sqtgg(): not enough memory for the FAH\n"); return -9; } for (i = 0; i <= pr_max; ++i) fifot[i] = fifo[i]; free((char *)fifo); fifo=fifot; fifot=NULL; fifo[*p_k] = alloc_fifo(GetImNx(im_m)); pr_max = *p_k; } else if (fifo[*p_k] == NULL){ fifo[*p_k] = alloc_fifo(GetImNx(im_m)); } fifo_add(fifo[*p_k], (long int)p_k); *p_k |= REF_PIX_MSB; } } clear_fifo(pf); } } free((char *)fifo); pm = (PIX_TYPE *)GetImPtr(im_m); LOOPDN(i, GetImNPix(im_m)){ *pm ^= REF_PIX_MSB; pm++; } return NO_ERROR; } #include "i32_undef.h" #undef PR_MAX #undef MSK #undef REF_TYPE #undef REF_PIX_MSB ERROR_TYPE sqtgpla(IMAGE *im_m, IMAGE *im_r, int graph) { switch (GetImDataType(im_m)){ case t_INT32: i32_sqtgpla(im_m, im_r, graph); break; default: (void)sprintf(buf, "ERROR in sqtgpla(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "u32_def.h" #define MSK 3 /* pixels having this value in reference image will not be further processed */ #define INQUEUE 4 /* pixels having this value in reference image will not be further processed */ #define UNREACHEDVAL 0 ERROR_TYPE u32_sqtg_new(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of numerical geodesic mask I (CHAR) & O(INT32) ** im_r : image of reference set I (CHAR) ** graph: type of graph (2d || 3d) */ PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; unsigned long int i, ofs, npix; int k; PIX_TYPE *pm, *pm_k, *pm_crt, weight, prio; UCHAR *pr; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ return ERROR; } pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR) return ERROR; /* GLOUP pq free missing */ if (generic_framebox(im_r, box, MSK) == ERROR) return(ERROR); if (u32_framebox(im_m, box, PIX_MSB) == ERROR) return(ERROR); npix= GetImNPix(im_m); /* initialise the priority queue */ for (i=0; iprio = weight; pqd->offset= (long int)i+shift[k]; pqmininsert(pq, pqd); *pm_k |= PIX_MSB; } } *pm|=PIX_MSB; } else if (*pr==MSK) /* 2 -> will not be further processed */ *pm=PIX_MSB; pr++; pm++; } dumpxyz(im_m, 0, 47, 0, 10, 10); /* Ordered propagation of geodesic time function */ pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); while (pqminremove(pq, apqd) != NULL){ ofs=apqd[0]->offset; prio=apqd[0]->prio; free((void*) *apqd); pm_crt=pm+ofs; *pm_crt^=PIX_MSB; for (k=0; kprio = prio + *pm_crt + *pm_k; pqd->offset= (long int)ofs+shift[k]; pqmininsert(pq, pqd); *pm_k |= PIX_MSB; } *pm_crt=prio; *pm_crt|=PIX_MSB; } free_pq(pq); LOOPDN(i, GetImNPix(im_m)){ if ( ((*pm & PIX_MSB) == 0) || (*pr==MSK) ) *pm=UNREACHEDVAL; else *pm ^= PIX_MSB; pm++; if(*pr==INQUEUE) *pr=0; else *pr=1; pr++; } return NO_ERROR; } #include "u32_undef.h" #undef MSK #undef INQUEUE #undef UNREACHEDVAL ERROR_TYPE sqtg(IMAGE *im_m, IMAGE *im_r, int graph) { /* 20160703: version with pq and symmetric time calculations (necessary for minimal path computations) */ if (szgeocompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtg(): input images must be of same geometry\n"); errputstr(buf); return ERROR; } switch (GetImDataType(im_m)){ case t_INT32: /* but call unsigned long int */ u32_sqtg_new(im_m, im_r, graph); break; default: (void)sprintf(buf, "ERROR in sqtg(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" #define PIX_TYPE_OUT UINT32 #define t_PIX_TYPE_OUT t_UINT32 #define MSK 3 /* pixels having this value in reference image will not be further processed */ #define RETRIEVED 2 /* pixels retrieved from pq queue get this value in reference*/ IMAGE *uc_sqtgsym(IMAGE *im_m, IMAGE *im_r, int graph) { /* ** im_m : image of grey level geodesic mask I (CHAR) ** im_r : image of reference set I (CHAR) ** graph: type of graph (2d || 3d) ** assume that reference points have a zero value in im_m !!! ** Note: symmetric version of sqtg achieved on 20150814 ** by Pierre Soille ** Adpated from http://10.1016/0167-8655(94)90113-9 ** see also http://10.1007/978-3-662-05088-0 */ IMAGE *imout; PIX_TYPE_OUT *po, weight, prio, prio_crt; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; unsigned long int i, ofs, npix; int k; PIX_TYPE *pm, *pm_k, *pm_crt; PIX_TYPE *pr, *pr_k, *pr_crt; long int shift[27]; int box[6]; if (GetImNy(im_m) == 1) {BOX_1D;} else if (GetImNz(im_m) == 1) {BOX_2D;} else {BOX_3D;} imout=create_image(t_PIX_TYPE_OUT, GetImNx(im_m), GetImNy(im_m), GetImNz(im_m)); if (imout==NULL) return NULL; pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imout); return NULL; } /* take graph into account */ if (set_seq_shift(GetImNx(im_m), GetImNy(im_m), GetImNz(im_m), graph, shift) == ERROR){ free_image(imout); free_pq(pq); return NULL; } /* border and output initialisations */ if (generic_framebox(im_r, box, MSK) == ERROR){ free_image(imout); free_pq(pq); return NULL; } if (generic_framebox(im_m, box, PIX_MSB) == ERROR){ free_image(imout); free_pq(pq); return NULL; } if (u32_blank(imout, UINT32_MAX) == ERROR){ free_image(imout); free_pq(pq); return NULL; } if (u32_framebox(imout, box, 0) == ERROR){ free_image(imout); free_pq(pq); return NULL; } npix= GetImNPix(im_m); pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); po = (PIX_TYPE_OUT *)GetImPtr(imout); /* initialise the priority queue */ for (i=0; iprio = weight; pqd->offset= (long int)i+shift[k]; pqmininsert(pq, pqd); } } } } pr++; pm++; po++; } /* Ordered propagation of geodesic time function */ pm = (PIX_TYPE *)GetImPtr(im_m); pr = (UCHAR *)GetImPtr(im_r); po = (PIX_TYPE_OUT *)GetImPtr(imout); while (pqminremove(pq, apqd) != NULL){ ofs=apqd[0]->offset; prio=apqd[0]->prio; free((void*) *apqd); if (*(pr+ofs)==RETRIEVED) /* was already retrieved (with lower priority)*/ continue; *(pr+ofs)=RETRIEVED; /* ensure no further processing from this pixel */ pm_crt=pm+ofs; pr_crt=pr+ofs; for (k=0; kprio = prio_crt; pqd->offset= (long int)ofs+shift[k]; pqmininsert(pq, pqd); } } } free_pq(pq); if (generic_framebox(im_m, box, 0) == ERROR){ free_image(imout); return NULL; } return imout; } #include "uc_undef.h" #undef MSK #undef PIX_TYPE_OUT #undef t_PIX_TYPE_OUT #undef RETRIEVED IMAGE *sqtgsym(IMAGE *im_m, IMAGE *im_r, int graph) { if (szcompat(im_m, im_r) != NO_ERROR){ (void) sprintf(buf, "sqtgsym(): input images must be of same geometry and type\n"); errputstr(buf); return NULL; } switch (GetImDataType(im_m)){ case t_UCHAR: return(uc_sqtgsym(im_m, im_r, graph)); break; default: (void)sprintf(buf, "ERROR in sqtgsym(): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/grid.c000066400000000000000000000426541467232417700166650ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #ifdef OPENMP #include #endif #include "miallib.h" extern double round(double ); typedef float COOR_TYPE ; /** \addtogroup group_proj * @{ */ #include "uc_def.h" IMAGE *uc_grid(IMAGE *im, IMAGE *roi, IMAGE *imx, IMAGE *imy, float alpha) { /* ** author: Pierre Soille - EC Joint Research Centre (1st 2005-04-06) ** IMAGE *im: base image to interpolate from ** IMAGE *roi: same size as im with 1 if data, 0 otherwise (UCHAR image) ** IMAGE *imx: image of x-coordinates where to interpolate ** IMAGE *imy: image of y-coordinates where to interpolate ** float alpha: alpha value (Park and Schowengerdt, 1983) ** returns: an image with interpolated values. Overshoots and undershoots are cut off. ** comment: Bicubic interpolation (Keys, 1981). */ IMAGE *imout; PIX_TYPE *p, *pcrt, *pout; UCHAR *proi; COOR_TYPE *px, *py, xcoor, ycoor, x1, x2; long int x, y, nix=GetImNx(im), niy, nx, ny, idx, xcoorint, ycoorint; double rax, rbx, rcx, rdx; /* values of interpolation function along x */ double ray, rby, rcy, rdy; /* values of interpolation function along y */ double val; double val1, val2; /* used for linear interpolation */ int shft0=-nix-1, shft1=-nix, shft2=-nix+1, shft3=-nix+2; int shft4=-1 , shft5=0, shft6=1, shft7=2; int shft8=nix-1, shft9=nix, shft10=nix+1, shft11=nix+2; int shft12=2*nix-1, shft13=2*nix, shft14=2*nix+1, shft15=nix+2; nix=GetImNx(im); niy=GetImNy(im); nx=GetImNx(imx); ny=GetImNy(imx); imout=(IMAGE *)create_image(GetImDataType(im),nx, ny, 1); if(imout==NULL) return NULL; p=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); proi=(UCHAR *)GetImPtr(roi); px=(COOR_TYPE *)GetImPtr(imx); py=(COOR_TYPE *)GetImPtr(imy); if (alpha<0.0){ /* bicubic interpolation */ for(x=0;x=nix) || (ycoorint-1<0) || (ycoorint+2>=niy) ) continue; /* at least one point for interpolation not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; x1=xcoor-(long int)xcoor; x2=x1+1.0; rax=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rbx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcx=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=ycoor-(long int)ycoor; x2=x1+1.0; ray=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rby=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcy=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdy=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; pcrt=p+xcoorint+ycoorint*nix; val = *(pcrt+shft0) * rbx * rby ; val += *(pcrt+shft1) * rax * rby ; val += *(pcrt+shft2) * rcx * rby ; val += *(pcrt+shft3) * rdx * rby ; val += *(pcrt+shft4) * rbx * ray ; val += *(pcrt+shft5) * rax * ray ; val += *(pcrt+shft6) * rcx * ray ; val += *(pcrt+shft7) * rdx * ray ; val += *(pcrt+shft8) * rbx * rcy ; val += *(pcrt+shft9) * rax * rcy ; val += *(pcrt+shft10) * rcx * rcy ; val += *(pcrt+shft11) * rdx * rcy ; val += *(pcrt+shft12) * rbx * rdy ; val += *(pcrt+shft13) * rax * rdy ; val += *(pcrt+shft14) * rcx * rdy ; val += *(pcrt+shft15) * rdx * rdy ; if (valPIX_MAX) val=PIX_MAX; #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==0.0){ /* linear interpolation */ printf("Linear interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint+1>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; pcrt=p+xcoorint+ycoorint*nix; if(xcoorint==xcoor){ val1=*pcrt; val2=*(pcrt+nix); } else{ val1 = *pcrt+ (*(pcrt+1)-*pcrt)*(xcoor-xcoorint); val2 = *(pcrt+nix)+ (*(pcrt+nix+1)-*(pcrt+nix))*(xcoor-xcoorint); } if(ycoorint==ycoor) val = val1; else val = val1 + (val2-val1)*(ycoor-ycoorint); #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==1.0){ /* nearest neighbour interpolation */ printf("Nearest neighbour interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; *(pout+idx)=*(p+xcoorint+ycoorint*nix); } } } return(imout); } #include "uc_undef.h" #include "us_def.h" IMAGE *us_grid(IMAGE *im, IMAGE *roi, IMAGE *imx, IMAGE *imy, float alpha) { /* ** author: Pierre Soille - EC Joint Research Centre (1st 2005-04-06) ** IMAGE *im: base image to interpolate from ** IMAGE *roi: same size as im with 1 if data, 0 otherwise (UCHAR image) ** IMAGE *imx: image of x-coordinates where to interpolate ** IMAGE *imy: image of y-coordinates where to interpolate ** float alpha: alpha value (Park and Schowengerdt, 1983) ** returns: an image with interpolated values. Overshoots and undershoots are cut off. ** comment: Bicubic interpolation (Keys, 1981). */ IMAGE *imout; PIX_TYPE *p, *pcrt, *pout; UCHAR *proi; COOR_TYPE *px, *py, xcoor, ycoor, x1, x2; long int x, y, nix=GetImNx(im), niy, nx, ny, idx, xcoorint, ycoorint; double rax, rbx, rcx, rdx; /* values of interpolation function along x */ double ray, rby, rcy, rdy; /* values of interpolation function along y */ double val; double val1, val2; /* used for linear interpolation */ int shft0=-nix-1, shft1=-nix, shft2=-nix+1, shft3=-nix+2; int shft4=-1 , shft5=0, shft6=1, shft7=2; int shft8=nix-1, shft9=nix, shft10=nix+1, shft11=nix+2; int shft12=2*nix-1, shft13=2*nix, shft14=2*nix+1, shft15=nix+2; nix=GetImNx(im); niy=GetImNy(im); nx=GetImNx(imx); ny=GetImNy(imx); imout=(IMAGE *)create_image(GetImDataType(im),nx, ny, 1); if(imout==NULL) return NULL; p=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); proi=(UCHAR *)GetImPtr(roi); px=(COOR_TYPE *)GetImPtr(imx); py=(COOR_TYPE *)GetImPtr(imy); if (alpha<0.0){ /* bicubic interpolation */ for(x=0;x=nix) || (ycoorint-1<0) || (ycoorint+2>=niy) ) continue; /* at least one point for interpolation not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; x1=xcoor-(long int)xcoor; x2=x1+1.0; rax=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rbx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcx=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=ycoor-(long int)ycoor; x2=x1+1.0; ray=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rby=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcy=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdy=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; pcrt=p+xcoorint+ycoorint*nix; val = *(pcrt+shft0) * rbx * rby ; val += *(pcrt+shft1) * rax * rby ; val += *(pcrt+shft2) * rcx * rby ; val += *(pcrt+shft3) * rdx * rby ; val += *(pcrt+shft4) * rbx * ray ; val += *(pcrt+shft5) * rax * ray ; val += *(pcrt+shft6) * rcx * ray ; val += *(pcrt+shft7) * rdx * ray ; val += *(pcrt+shft8) * rbx * rcy ; val += *(pcrt+shft9) * rax * rcy ; val += *(pcrt+shft10) * rcx * rcy ; val += *(pcrt+shft11) * rdx * rcy ; val += *(pcrt+shft12) * rbx * rdy ; val += *(pcrt+shft13) * rax * rdy ; val += *(pcrt+shft14) * rcx * rdy ; val += *(pcrt+shft15) * rdx * rdy ; if (valPIX_MAX) val=PIX_MAX; #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==0.0){ /* linear interpolation */ printf("Linear interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint+1>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; pcrt=p+xcoorint+ycoorint*nix; if(xcoorint==xcoor){ val1=*pcrt; val2=*(pcrt+nix); } else{ val1 = *pcrt+ (*(pcrt+1)-*pcrt)*(xcoor-xcoorint); val2 = *(pcrt+nix)+ (*(pcrt+nix+1)-*(pcrt+nix))*(xcoor-xcoorint); } if(ycoorint==ycoor) val = val1; else val = val1 + (val2-val1)*(ycoor-ycoorint); #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==1.0){ /* nearest neighbour interpolation */ printf("Nearest neighbour interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; *(pout+idx)=*(p+xcoorint+ycoorint*nix); } } } return(imout); } #include "us_undef.h" #include "s_def.h" IMAGE *s_grid(IMAGE *im, IMAGE *roi, IMAGE *imx, IMAGE *imy, float alpha) { /* ** author: Pierre Soille - EC Joint Research Centre (1st 2005-04-06) ** IMAGE *im: base image to interpolate from ** IMAGE *roi: same size as im with 1 if data, 0 otherwise (UCHAR image) ** IMAGE *imx: image of x-coordinates where to interpolate ** IMAGE *imy: image of y-coordinates where to interpolate ** float alpha: alpha value (Park and Schowengerdt, 1983) ** returns: an image with interpolated values. Overshoots and undershoots are cut off. ** comment: Bicubic interpolation (Keys, 1981). */ IMAGE *imout; PIX_TYPE *p, *pcrt, *pout; UCHAR *proi; COOR_TYPE *px, *py, xcoor, ycoor, x1, x2; long int x, y, nix=GetImNx(im), niy, nx, ny, idx, xcoorint, ycoorint; double rax, rbx, rcx, rdx; /* values of interpolation function along x */ double ray, rby, rcy, rdy; /* values of interpolation function along y */ double val; double val1, val2; /* used for linear interpolation */ int shft0=-nix-1, shft1=-nix, shft2=-nix+1, shft3=-nix+2; int shft4=-1 , shft5=0, shft6=1, shft7=2; int shft8=nix-1, shft9=nix, shft10=nix+1, shft11=nix+2; int shft12=2*nix-1, shft13=2*nix, shft14=2*nix+1, shft15=nix+2; nix=GetImNx(im); niy=GetImNy(im); nx=GetImNx(imx); ny=GetImNy(imx); imout=(IMAGE *)create_image(GetImDataType(im),nx, ny, 1); if(imout==NULL) return NULL; p=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); proi=(UCHAR *)GetImPtr(roi); px=(COOR_TYPE *)GetImPtr(imx); py=(COOR_TYPE *)GetImPtr(imy); if (alpha<0.0){ /* bicubic interpolation */ for(x=0;x=nix) || (ycoorint-1<0) || (ycoorint+2>=niy) ) continue; /* at least one point for interpolation not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; x1=xcoor-(long int)xcoor; x2=x1+1.0; rax=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rbx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcx=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdx=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=ycoor-(long int)ycoor; x2=x1+1.0; ray=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rby=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; x1=1.0-x1; x2=x1+1.0; rcy=(alpha+2.0) * x1*x1*x1 - (alpha+3.0) * x1*x1 + 1.0; rdy=alpha * x2*x2*x2 - 5.0 * alpha * x2*x2 + 8.0 * alpha * x2 - 4.0 * alpha; pcrt=p+xcoorint+ycoorint*nix; val = *(pcrt+shft0) * rbx * rby ; val += *(pcrt+shft1) * rax * rby ; val += *(pcrt+shft2) * rcx * rby ; val += *(pcrt+shft3) * rdx * rby ; val += *(pcrt+shft4) * rbx * ray ; val += *(pcrt+shft5) * rax * ray ; val += *(pcrt+shft6) * rcx * ray ; val += *(pcrt+shft7) * rdx * ray ; val += *(pcrt+shft8) * rbx * rcy ; val += *(pcrt+shft9) * rax * rcy ; val += *(pcrt+shft10) * rcx * rcy ; val += *(pcrt+shft11) * rdx * rcy ; val += *(pcrt+shft12) * rbx * rdy ; val += *(pcrt+shft13) * rax * rdy ; val += *(pcrt+shft14) * rcx * rdy ; val += *(pcrt+shft15) * rdx * rdy ; if (valPIX_MAX) val=PIX_MAX; #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==0.0){ /* linear interpolation */ printf("Linear interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint+1>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; pcrt=p+xcoorint+ycoorint*nix; if(xcoorint==xcoor){ val1=*pcrt; val2=*(pcrt+nix); } else{ val1 = *pcrt+ (*(pcrt+1)-*pcrt)*(xcoor-xcoorint); val2 = *(pcrt+nix)+ (*(pcrt+nix+1)-*(pcrt+nix))*(xcoor-xcoorint); } if(ycoorint==ycoor) val = val1; else val = val1 + (val2-val1)*(ycoor-ycoorint); #if FLOATING *(pout+idx)=(PIX_TYPE)val; #else *(pout+idx)=(PIX_TYPE)round(val); /* round to nearest integer C99! */ #endif } } } else if (alpha==1.0){ /* nearest neighbour interpolation */ printf("Nearest neighbour interpolation\n"); for(x=0;x=nix) || (ycoorint<0) || (ycoorint>=niy) ) continue; /* nearest neighbour not in image */ if (*(proi+xcoorint+nix*ycoorint)==0) continue; *(pout+idx)=*(p+xcoorint+ycoorint*nix); } } } return(imout); } #include "s_undef.h" /** * * * @param im * @param roi * @param imx * @param imy * @param alpha * * @return */ IMAGE *grid(IMAGE *im, IMAGE *roi, IMAGE *imx, IMAGE *imy, float alpha) { if(szcompat(imx,imy)==ERROR){ sprintf(buf,"images imx and imy must be of the same size and type\n"); errputstr(buf); return NULL; } if( GetImDataType(imx)!=t_FLOAT){ sprintf(buf,"images imx and imy must be of type t_FLOAT\n"); errputstr(buf); return NULL; } switch (GetImDataType(im)){ case t_UCHAR: return(uc_grid(im, roi, imx, imy, alpha)); break; case t_USHORT: return(us_grid(im, roi, imx, imy, alpha)); break; case t_SHORT: return(s_grid(im, roi, imx, imy, alpha)); break; default: (void)sprintf(buf, "ERROR in grid(): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/gsl.c000066400000000000000000000074021467232417700165150ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" double *solve(double *a_data, double *b_data, int size) { double *out; gsl_matrix_view m = gsl_matrix_view_array (a_data, size, size); gsl_vector_view b = gsl_vector_view_array (b_data, size); gsl_vector *x = gsl_vector_alloc (size); int i, s; out=(double *)malloc(size*sizeof(double)); gsl_permutation * p = gsl_permutation_alloc (size); gsl_linalg_LU_decomp (&m.matrix, p, &s); gsl_linalg_LU_solve (&m.matrix, p, &b.vector, x); gsl_permutation_free (p); for(i=0;i. ***********************************************************************/ #include #include #include #include "math.h" #include "miallib.h" #include "time.h" #ifdef OPENMP #include #endif extern void tracelinecorrect(int, int, int, int, long int *, int *, int, int); /** \addtogroup group_erodil * @{ */ /* feature for border effect corrected on 2003 April 4th ! Emilio ist zu hause (steicht die Persiennen) */ #include "uc_def.h" void uc_lherkpldil(PIX_TYPE *pf, int n, int k, int o, int t) { /* ** author: Pierre Soille ** first: 29-07-99 ** last: 30-09-99 ** UCHAR *pf: I/O line buffer ** int n: number of pixels in I/O line buffer ** int k: length of line segment in pixels ** int o: origin of line segment \in {0,1,...,(k*t)-1} ** int t: periodicity */ int i, j; int nb = n/(k*t); int kmott=(k-1)*t; PIX_TYPE *pg, *pgt, *ph, *pht, *pff, *pfb, *pgmk, *phpk, *pfend; /* allocate memory */ #if (SIGNED==0) pg = pgt = (PIX_TYPE *)calloc(n+2*k*t,sizeof(PIX_TYPE)); ph = pht = (PIX_TYPE *)calloc(n+2*k*t,sizeof(PIX_TYPE)); #else pg = pgt = (PIX_TYPE *)malloc((n+2*k*t)*sizeof(PIX_TYPE)); ph = pht = (PIX_TYPE *)malloc((n+2*k*t)*sizeof(PIX_TYPE)); for (i=0;i0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MAX(*pff,*pgmk); *ph = MAX(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MAX(*pff,*pgmk); *ph = MAX(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MAX(*pff,*pgmk); *ph = MAX(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MAX(*pff,*pgmk); *ph = MAX(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int *)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; printf("uc_lherkpldil_omp coucou l1=%d l2=%d la=%d incx=%d incy=%d inc=% d\n", l1, l2, la, incx, incy, inc); #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MIN(*pff,*pgmk); *ph = MIN(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MIN(*pff,*pgmk); *ph = MIN(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MIN(*pff,*pgmk); *ph = MIN(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf0; i--, pg++, ph--, pff++, pgmk++, pfb--, phpk--){ *pg = MIN(*pff,*pgmk); *ph = MIN(*pfb,*phpk); } } pg=pgt+k*t + (k-1)*t - o ; ph=pht+k*t - o; pfend=pf+n; for (; pf (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i (k-1)*t){ (void)sprintf(buf,"Invalid origin, must be in 0,...,(k-1)*t\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; o=(k*t)-t-o; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(nx,sizeof(long int)); rlc = (int*)calloc(nx,sizeof(int)); nxmtk = (nx%(t*k)) == 0 ? nx : nx + t*k-(nx%(t*k)); tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* update rlc with running sums for omp version 20120427 */ for(i=1;i= 0 ? l1:l2; #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,m) #endif for (i=0; i. ***********************************************************************/ /** @file * Translation invariant rank operator along line segments \cite soille-talbot2001 * @author Pierre Soille */ #include #include #include #include "math.h" #include "miallib.h" #include "time.h" #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif extern void tracelinecorrect(int, int, int, int , long int *, int *, int , int); /** \addtogroup group_rank * @{ */ #include "uc_def.h" IMAGE *uc_lrankti(IMAGE *im, int dx, int dy, int k, int rank, int o, int t, int tr) { /* ** im: a 2D uc_ image ** dx: offset of SE along x from origin ** dy: offset of SE along y from origin ** k: extent of SE in pixels ** rank: ** o: origin ** t: among all possible SEs along the Bresenham line with slope dy/dx, select the one with index t ** transpose: -1 for transposing, 1 for not transposing */ IMAGE *imout; PIX_TYPE *picrt, *pocrt, val; PIX_TYPE *f, *fo; int ncol=GetImNx(im); int nlin=GetImNy(im); long int *p, *ptmp; int *rlc; int inc, incx, incy; int pxf = 0, pyf = 0, nx, nxori, i, j, l, l1, l2, la; int period, rj, j0, cycle, m, n; int box[6]; int trank; int hst[257]; /* histogram array */ int thcrt; double rindex = (double)rank/(k+1); int *shft, *shfti, *shfto, nshft; /* for SE */ period = max(abs(dx),abs(dy)); /* printf("period=%d\n", period); */ if (rank < 1 || rank > k){ (void)sprintf(buf,"Invalid rank value, must be in 1,...,k\n"); stdputstr(buf); return NULL; } if (tr != -1 && tr != 1){ (void)sprintf(buf,"Invalid tr flag value value, must be in 1 or -1 \n"); stdputstr(buf); return NULL; } if (k < period){ (void)sprintf(buf,"Invalid length, must be larger or equal to periodicity\n"); stdputstr(buf); return NULL; } if (o < 0 || o > k-1){ (void)sprintf(buf,"Invalid origin, must be in 0,...,k-1\n"); stdputstr(buf); return NULL; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return NULL; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; /* o=(k*t)-t-o; well don;t understand this any more see herk.c */ } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } nxori=nx; nx+=((int)(k/period)+1); /* longer so as to handle transposition without to much fuss */ p = (long int*)calloc(sizeof(long int),nx); rlc = (int*)calloc(sizeof(int),nx); box[0]=box[1]=box[2]=box[3]=k; /* add frame to avoid border problems */ box[4]=box[5]=0; generic_addframebox(im, box, PIX_MAX); /* 255 for don't care */ ncol=GetImNx(im); f=(PIX_TYPE *)GetImPtr(im)+k+ncol*k; /* original origin in enlarged image */ tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* allocate and initialise shifts arrays */ nshft=k; /* length of full SE */ shft=(int *)calloc(nshft, sizeof(int)); /* all pixels of SE */ for (i=0; i= 0 ? l1:l2; for (n=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } for (l=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } j += rlc[n]; if (j>nxori) /* perhaps do the same for incr. dcr. simulatneously */ j=nxori; for (n=l1; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } for (n=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } free((void *) shft); free((void *) shfti); free((void *) shfto); free(ptmp); free(rlc); subframebox(im, box); subframebox(imout, box); return imout; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_lrankti(IMAGE *im, int dx, int dy, int k, int rank, int o, int t, int tr) { /* ** im: a 2D us_ image ** dx: offset of SE along x from origin ** dy: offset of SE along y from origin ** k: extent of SE in pixels ** rank: ** o: origin ** t: among all possible SEs along the Bresenham line with slope dy/dx, select the one with index t ** transpose: -1 for transposing, 1 for not transposing */ IMAGE *imout; PIX_TYPE *picrt, *pocrt, val; PIX_TYPE *f, *fo; int ncol=GetImNx(im); int nlin=GetImNy(im); long int *p, *ptmp; int *rlc; int inc, incx, incy; int pxf = 0, pyf = 0, nx, nxori, i, j, l, l1, l2, la; int period, rj, j0, cycle, m, n; int box[6]; int trank; int hst[257]; /* histogram array */ int thcrt; double rindex = (double)rank/(k+1); int *shft, *shfti, *shfto, nshft; /* for SE */ period = max(abs(dx),abs(dy)); /* printf("period=%d\n", period); */ if (rank < 1 || rank > k){ (void)sprintf(buf,"Invalid rank value, must be in 1,...,k\n"); stdputstr(buf); return NULL; } if (tr != -1 && tr != 1){ (void)sprintf(buf,"Invalid tr flag value value, must be in 1 or -1 \n"); stdputstr(buf); return NULL; } if (k < period){ (void)sprintf(buf,"Invalid length, must be larger or equal to periodicity\n"); stdputstr(buf); return NULL; } if (o < 0 || o > k-1){ (void)sprintf(buf,"Invalid origin, must be in 0,...,k-1\n"); stdputstr(buf); return NULL; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return NULL; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; /* o=(k*t)-t-o; well don;t understand this any more see herk.c */ } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } nxori=nx; nx+=((int)(k/period)+1); /* longer so as to handle transposition without to much fuss */ p = (long int*)calloc(sizeof(long int),nx); rlc = (int*)calloc(sizeof(int),nx); box[0]=box[1]=box[2]=box[3]=k; /* add frame to avoid border problems */ box[4]=box[5]=0; us_addframebox(im, box, PIX_MAX); /* 255 for don't care */ ncol=GetImNx(im); f=(PIX_TYPE *)GetImPtr(im)+k+ncol*k; /* original origin in enlarged image */ tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* allocate and initialise shifts arrays */ nshft=k; /* length of full SE */ shft=(int *)calloc(nshft, sizeof(int)); /* all pixels of SE */ for (i=0; i= 0 ? l1:l2; for (n=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } for (l=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } j += rlc[n]; if (j>nxori) /* perhaps do the same for incr. dcr. simulatneously */ j=nxori; for (n=l1; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } for (n=0; n= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } if (j0==1) rj=period; for (cycle=rj; cycle= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } /* process along line */ val=i; *pocrt=val; for (m=1; m thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } } free((void *) shft); free((void *) shfti); free((void *) shfto); free(ptmp); free(rlc); subframebox(im, box); subframebox(imout, box); return imout; } #include "us_undef.h" IMAGE *lrankti(IMAGE *im, int dx, int dy, int k, int rank, int o, int t, int tr) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_lrankti(im, dx, dy, k, rank, o, t, tr)); case t_USHORT: return(us_lrankti(im, dx, dy, k, rank, o, t, tr)); default: (void)sprintf(buf,"lrankti(): invalid pixel type\n"); errputstr(buf); return NULL; } return NULL; } /*@}*/ jeolib-miallib-1.1.6/core/c/histo.c000066400000000000000000000217071467232417700170620ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2013-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* Histrogram matching routines. by Pierre Soille first 20130430 scope: developed for producing a pleasing mosaic of SPOT-5 GMES_CORE003 data using TerraColor as reference mosaic. */ #include #include #include #include "miallib.h" /** \addtogroup group_stat * @{ */ int match2d(long int cf, IMAGE *cdf_2d, int x, int y, int dir) { /* Given a cumulative frequency value cf, find in the 2-D cumulative distribution frequency cdf_2d the matching value starting at position (x,y) and proceeding along direction dir (0 for horizontal and 1 for vertical). Typically (x,y) refers to a point on the upper or left border of cdf_2d. Note that for arbitrary scan, the cf values need to be rescaled accordingly. By: Pierre Soille First: 20130430 */ unsigned int *p2d; int i, n=GetImNx(cdf_2d); /* default n for dir== 0 */ int ofs, inc; int out=0; int flag=0; //printf("cf=%d\n", cf); ofs=x+y*GetImNx(cdf_2d); p2d=(unsigned int *)GetImPtr(cdf_2d); if (cf==50802){ printf("x=%d y=%d dir=%d before cf =%ld p2d=%ud\n p2dmax=%d", x, y, dir, cf, p2d[x+(y+1)*n-1], p2d[GetImNx(cdf_2d)*GetImNy(cdf_2d)-1]); flag=1; } if (dir==0){ cf=(p2d[x+y*n-1]*cf)/p2d[GetImNx(cdf_2d)*GetImNy(cdf_2d)-1]; inc=1; } else{ n=GetImNy(cdf_2d); cf=(p2d[x+(GetImNy(cdf_2d)-1)*GetImNx(cdf_2d)]*cf)/p2d[GetImNx(cdf_2d)*GetImNy(cdf_2d)-1]; inc=GetImNx(cdf_2d); } //printf("\t after cf =%ld\n", cf); for(i=1;i. ***********************************************************************/ #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" #include "pqueue.h" #ifdef OPENMP #include #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif /** \addtogroup group_dem * @{ */ #include "us_def.h" IMAGE *us_htop(IMAGE *dem, IMAGE *imdir) { /* This function was created following a discussion with Sergio Rosim and Joao Oliveira from INPE (visit to JRC on 14--15/11/2013. by Pierre Soille first: 20131118 first working: 20131126 */ IMAGE *imhtop; UCHAR *pdir; PIX_TYPE *pdem, *phtop; int dirto[9]={0,2,1,4,3,8,7,6,5}; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; int flag; long int ofs, ofscrt, nx, ny, nz, npix, npixlast; long int i, k; int shft[9]; int shft1, shft2, shft3, shft4, shft5, shft6, shft7, shft8; nx = GetImNx(dem); ny = GetImNy(dem); nz = GetImNz(dem); npix=nx*ny*nz; npixlast=nx*ny*nz-nx-1; shft5 = -nx-1; shft3 = -nx; shft7 = -nx+1; shft1 = -1; shft2 = +1; shft6 = nx-1; shft4 = +nx; shft8 = nx+1; shft[5]=shft5; shft[3]=shft3; shft[7]=shft7; shft[1]=shft1; shft[0]= 0; shft[2]=shft2; shft[6]=shft6; shft[4]=shft4; shft[8]=shft8; pdir=(UCHAR *)GetImPtr(imdir); pdem=(PIX_TYPE *)GetImPtr(dem); /* create an image for storing the htop values */ imhtop = (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imhtop == NULL){ (void)sprintf(buf,"htop(): not enough memory for output image!\n"); errputstr(buf); return(imhtop); } phtop=(PIX_TYPE *)GetImPtr(imhtop); /* create priority queue */ pq = pqinit(NULL, 10000); if (pq == NULL){ free_image(imhtop); return NULL; } /* init pqueue: we want only actual local extrema in the queue. Because we proceed here with a squential scan of all image pixels, we need pdir[i+shft[k]]&127 in the test below ! */ for (i=nx+1; iprio = pdem[ofs]; pqd->offset= (long int)ofs; pqinsert(pq, pqd); } } } /* here we go: a pixel is inserted in the queue only once all the neighbours flowing to it have transferred their height to this pixel. */ while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; free((char*) *apqd); if( (pdir[ofs]) !=0){ ofscrt=ofs+shft[pdir[ofs]]; phtop[ofscrt]=MAX(phtop[ofs],phtop[ofscrt]); pdir[ofs]|=128; /* has propagated its height */ flag=1; for (k=1; k<9; k++){ if (pdir[ofscrt+shft[k]]==dirto[k]){ flag=0; break; } } if (flag){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = pdem[ofscrt]; pqd->offset= (long int)ofscrt; pqinsert(pq, pqd); } } } /* reset directions */ #pragma omp parallel for for (i=0; i. ***********************************************************************/ /** * @file hull.c * @author Pierre Soille * @date * * * @details see also @cite soille2000fi */ #include #include #include "math.h" #include "miallib.h" #ifdef TIMING #include #include typedef struct tms Ttime ; #endif #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif extern void tracelinecorrect(int, int, int, int , long int *, int *, int , int); /** \addtogroup group_opclo * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_hpclose(IMAGE *im, int dx, int dy) { /* IMAGE *im: pointer to an image structure ** int dx: used for defining a slope ** int dy: used for defining a slope ** returns: a new image holding the closing of ** the image im by the two half-planes whose ** slope equals dy/dx */ IMAGE *imout; PIX_TYPE *fi, *fo, maxi; int nlin, ncol; long int *p, *ptmp, mbuf, offset; int *rlc; int inc,incx,incy,pxf=0,pyf=0,nx,i,j,x,l,l1,l2,la; #ifdef TIMING Ttime avant, apres; times( &avant ); #endif /* ** create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), (int)1); if (imout == NULL){ (void)sprintf(buf,"generic_hpclose(): not enough memory!\n"); errputstr(buf); return(imout); } nlin = GetImNy(im); ncol = GetImNx(im); fi=(PIX_TYPE *)GetImPtr(im); if (fi==NULL) return(NULL); fo=(PIX_TYPE *)GetImPtr(imout); /* ** set coordinates of p array */ if (dx<0){ dx = -dx; dy = -dy; } if (abs(dx) >= abs(dy)){ /* abs(slope)<=1 */ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; offset = (l1+nlin-1)*ncol; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; } } else{ /* abs(slope)>1 */ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; offset = 1-l1-ncol; if (dy > 0) /* horiz. translation */ pxf = (ncol-1); else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); tracelinecorrect(pxf,pyf,pxf+dx,pyf+dy,p,rlc,ncol,nx); /* ** close with 1st half-plane */ ptmp = p; inc = incx + ncol*incy; fi -= inc; fo -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; maxi = PIX_MIN; for (i=0; i maxi) maxi = *(fi+p[x]); for (x=0; x maxi) maxi = *(fi+p[x]); for (x=0; x maxi) maxi = *(fi+p[x]); for (x=0; x maxi) maxi = *(fi+p[x]); for (x=0; x= 0 ? l1:l2; maxi = PIX_MIN; printf("p[0]=%ld\n", p[0]); printf("p[1]=%ld\n", p[1]); printf("p[2]=%ld\n", p[2]); if (p[0]>nlin*ncol) printf("if this message gets printed, then there is a bug: pointing outside of image!!!\n"); for (i=0; i maxi) maxi = *(fi+p[x]); /* if maxi is smaller than previous closing */ if (maxi < *(fo+p[0])) for (x=0; x maxi) maxi = *(fi+p[x]); /* if maxi is smaller than previous closing */ if (maxi < *(fo+p[0])) for (x=0; x maxi) maxi = *(fi+p[x]); /* if maxi is smaller than previous closing */ if (maxi < *(fo+p[0])) for (x=0; x maxi) maxi = *(fi+p[x]); /* if maxi is smaller than previous closing */ if (maxi < *(fo+p[0])) for (x=0; x. ***********************************************************************/ #include #include #include #include "miallib.h" #ifdef TIMING #include #include typedef struct tms Ttime ; #endif #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif extern void indexx(size_t n, double arrin[], size_t indx[]); extern void bresenham(int x1, int y1, int x2, int y2, int pb[], double offset2[], int rlc[], int ncol); /** \addtogroup group_opclo * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_hpcloseti(IMAGE *im, int dx, int dy) { /* IMAGE *im: pointer to an image structure ** int dx: used for defining a slope ** int dy: used for defining a slope ** dx and dy must be integers with ** no common divisors other than 1 ** returns: a new image holding the closing of ** the image im by the two half-planes whose ** slope equals dy/dx */ IMAGE *imout; PIX_TYPE *fi, *fo, maxi; int nlin, ncol; int *p, *ptmp, *indxtmp, *rlc, *rlctmp, mbuf, offset; int inc,incx,incy,pxf=0,pyf=0,nx,i,j,k,x,l,l1,l2,la; int t; /* period */ // double offset2[25000]; /* must be dynamically allocated (t values) ... quick and dirty */ // int indxori[25000]; /* for order of t first pixels */ double *offset2=(double *)calloc(MAX(GetImNx(im), GetImNy(im))+1, sizeof(double)); size_t *indxori=(size_t *)calloc(MAX(GetImNx(im), GetImNy(im))+1, sizeof(size_t)); int *indx; /* for order of pixels along line */ int indxi; PIX_TYPE maxipl[512]; int adx, ady; /* absolute values of dx and dy */ int shift, nrlc; #ifdef TIMING Ttime avant, apres; times( &avant ); #endif /* ** create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), (int)1); if (imout == NULL){ free(offset2); free(indxori); (void)sprintf(buf,"generic_hpclose(): not enough memory!\n"); errputstr(buf); return(imout); } if (abs(dx)>=GetImNx(im)-1 || abs(dy)>=GetImNy(im)-1){ generic_blank(imout,PIX_MAX); free(offset2); free(indxori); return(imout); } nlin = GetImNy(im); ncol = GetImNx(im); fi=(PIX_TYPE *)GetImPtr(im); fo=(PIX_TYPE *)GetImPtr(imout); /* ** set coordinates of p array */ if (dx<0){ dx = -dx; dy = -dy; } t = MAX(abs(dx),abs(dy)); /* pixels appears with period t */ if (abs(dx) >= abs(dy)){ /* abs(slope)<=1 */ incx = 0; incy = 1; nx = ncol; l1 = (int)((nx-1)*fabs((double)dy/dx)+0.5); l2 = nlin; offset = (l1+nlin-1)*ncol; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; } } else{ /* abs(slope)>1 */ incx = -1; incy = 0; nx = nlin; l1 = (int)((nx-1)*fabs((double)dx/dy)+0.5); l2 = ncol; offset = 1-l1-ncol; if (dy > 0) /* horiz. translation */ pxf = (ncol-1); else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (int*)calloc(sizeof(int),(unsigned)nx); indx = (int*)calloc(sizeof(int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); bresenham(pxf,pyf,pxf+dx,pyf+dy,p,offset2,rlc,ncol); /* draw elementary pattern only of Bresenham line */ /* ** Get array of order of each pixel along the calculated line */ adx=abs(dx); ady=abs(dy); /* sort offsets in increasing order (first will be processed first etc.) */ indexx(t,offset2,indxori); free(offset2); for (i=0; i= abs(dy)){ /* abs(slope)<=1 */ l1=abs((int)((p[nx-1]-nx+1)/ncol)); offset = (l1+nlin-1)*ncol; } /* else no rounding problem ... */ /* initialize rlc array */ nrlc=0; /* number of rlc code for elementary Bresenham line */ for (i=0; iady){ for (i=1; i 1){ rlc++; *rlc = 1; } else *rlc += 1; } } else{ for (i=1; i= 0 ? l1:l2; maxi = PIX_MIN; for (i=0; i maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x= 0 ? l1:l2; maxi = PIX_MIN; for (i=0; inlin*ncol) printf("if this message gets printed, then there is a bug: pointing outside of image!!! dx=%d\t dy=%d\n", dx , dy); for (i=0; i maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[t-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x maxipl[indx[x]]) maxipl[indx[x]] = *(fi+p[x]); if(maxipl[0]maxipl[k]) maxipl[k]=maxipl[k-1]; maxi=maxipl[k-1]; for (x=0; x. ***********************************************************************/ /* macro definitions for unsigned long int data types */ #define FLOATING 0 #define SIGNED 1 #define SUM_TYPE long int #define OVFL_TEST 0 #define t_PIX_TYPE t_INT32 #define PIX_TYPE INT32 #define PIX_MIN INT32_MIN #define PIX_MAX INT32_MAX #define PIX_MSB 0x80000000 #define BitPerPixel 32 jeolib-miallib-1.1.6/core/c/i32_undef.h000066400000000000000000000020751467232417700175140ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef FLOATING #undef SIGNED #undef SUM_TYPE #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MSB #undef BitPerPixel jeolib-miallib-1.1.6/core/c/i64_def.h000066400000000000000000000022171467232417700171540ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for unsigned long int data types */ #define FLOATING 0 #define SIGNED 1 #define SUM_TYPE long int #define OVFL_TEST 0 #define t_PIX_TYPE t_INT64 #define PIX_TYPE INT64 #define PIX_MIN INT64_MIN #define PIX_MAX INT64_MAX #define PIX_MSB 0x8000000000000000 #define BitPerPixel 64 jeolib-miallib-1.1.6/core/c/i64_undef.h000066400000000000000000000020751467232417700175210ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef FLOATING #undef SIGNED #undef SUM_TYPE #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MSB #undef BitPerPixel jeolib-miallib-1.1.6/core/c/imem.c000066400000000000000000001070461467232417700166640ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** imem.c Purpose: IMAGE memory management functions @author Pierre Soille @version latest */ /** @defgroup group_mem Memory Functions * Functions dealing with image memory including associated Look-Up-Tables. * @{ */ #include #include #include #ifdef UNIX #include /* DOES NOT WORK ON WINDOWS */ #endif #ifdef RLIMIT #include #include #include #endif #include "miallib.h" #ifdef DMALLOC /* INCOMPATIBLE WITH EFENCE */ #include #endif #if (defined(XLISP)) extern void gc(); /*PSRM char buf[256]; PSRM*/ #endif /*************************************************************************/ #ifdef PYTHON void stdputstr(char *buf) { printf("%s", buf); } void errputstr(char *buf) { printf("%s", buf); } // see https://docs.python.org/2/c-api/memory.html // void* PyMem_Malloc(size_t n) // void PyMem_Free(void *p) // TYPE* PyMem_New(TYPE, size_t n) #define my_malloc(x) PyMem_Malloc(x) #define my_free_malloc(x) PyMem_Free(x) #define my_calloc(x,y) PyMem_New(x,y) /* x for TYPE and y for number of elements */ #define my_free_calloc(x) PyMem_Del(x) #elif !defined(XLISP) void stdputstr(char *buf) { fprintf(stdout,"%s\n", buf); } void errputstr(char *buf) { fprintf(stderr,"%s\n", buf); } #define my_malloc(x) malloc(x) #define my_free_malloc(x) free(x) #define my_calloc(x,y) (x *)calloc(y,sizeof(x)) #define my_free_calloc(x) free(x) #endif /**********************************/ int fprintfgenericnum(G_TYPE gval, int type) { if (type == t_GENERIC){ (void)sprintf(buf,"%d\n", (int)gval.generic_val); stdputstr(buf); } else if (type == t_UCHAR){ (void)sprintf(buf,"%d\n", (int)gval.uc_val); stdputstr(buf); } else if (type == t_USHORT){ (void)sprintf(buf,"%d\n", (int)gval.us_val); stdputstr(buf); } else if (type == t_SHORT){ (void)sprintf(buf,"%d\n", (int)gval.s_val); stdputstr(buf); } else if (type == t_INT32){ (void)sprintf(buf,"%d\n", (int)gval.i32_val); stdputstr(buf); } else if (type == t_UINT32){ (void)sprintf(buf,"%u\n", (unsigned) gval.u32_val); stdputstr(buf); } else if (type == t_INT64){ (void)sprintf(buf,"%ld\n", (long int)gval.i64_val); stdputstr(buf); } else if (type == t_UINT64){ (void)sprintf(buf,"%lu\n", (unsigned long) gval.u64_val); stdputstr(buf); } else if (type == t_FLOAT){ (void)sprintf(buf,"%f\n", gval.f_val); stdputstr(buf); } else if (type == t_DOUBLE){ (void)sprintf(buf,"%lf\n", (float)gval.d_val); stdputstr(buf); } else return(ERROR); return(NO_ERROR); } /*************************************************************************/ /** * create an IMAGE in memory and allocate the memory for the specified number of pixels * @param data_type integer for data type * @param nx long integer for number of columns * @param ny integer for number of lines * @param nz integer for number of planes * @return IMAGE pointer on success, NULL otherwise */ IMAGE *create_image(int data_type, long int nx, int ny, int nz) { IMAGE *im; void *p; mia_size_t nbyte; if (((mia_size_t)nx*ny*nz) == 0){ (void)sprintf(buf,"ERROR in create_image(data_type=%d, nx=%ld, ny=%d, nz=%d)\t \ invalid size parameters (must be positive) \n", \ data_type, nx, ny, nz); errputstr(buf); return(NULL); } #ifdef RLIMIT struct rusage usage[1]; struct rlimit rlim[1]; #endif #ifdef RLIMIT getrusage(RUSAGE_SELF, usage); getrlimit(RLIMIT_FSIZE, rlim); fprintf(stderr, "RLIMIT_FSIZE cur=%d\n", rlim->rlim_cur); fprintf(stderr, "RLIMIT_FSIZE max=%d\n", rlim->rlim_max); getrlimit(RLIMIT_DATA, rlim); fprintf(stderr, "RLIMIT_DATA cur=%d\n", rlim->rlim_cur); fprintf(stderr, "RLIMIT_DATA max=%d\n", rlim->rlim_max); getrlimit(RLIMIT_CORE, rlim); fprintf(stderr, "RLIMIT_CORE cur=%d\n", rlim->rlim_cur); fprintf(stderr, "RLIMIT_CORE max=%d\n", rlim->rlim_max); rlim->rlim_cur=RLIM_INFINITY; setrlimit(RLIMIT_CORE, rlim); getrlimit(RLIMIT_MEMLOCK, rlim); fprintf(stderr, "RLIMIT_MEMLOCK cur=%d\n", rlim->rlim_cur); fprintf(stderr, "RLIMIT_MEMLOCK max=%d\n", rlim->rlim_max); getrlimit(RLIMIT_AS, rlim); fprintf(stderr, "RLIMIT_AS cur=%d\n", rlim->rlim_cur); fprintf(stderr, "RLIMIT_AS max=%d\n", rlim->rlim_max); #endif im = (IMAGE *)calloc((size_t)1, sizeof(IMAGE)); if (im == NULL){ #if (defined(XLISP)) gc(); im = (IMAGE *)calloc((size_t)1, sizeof(IMAGE)); if (im == NULL){ (void)sprintf(buf,"ERROR in create_image(data_type=%d, nx=%ld, ny=%d, nz=%d) \ not enough memory\n", data_type, nx, ny, nz); errputstr(buf); xmem(); } return(im); #else (void)sprintf(buf,"ERROR in create_image(data_type=%d, nx=%ld, ny=%d, nz=%d) \ not enough memory\n", data_type, nx, ny, nz); errputstr(buf); return(im); #endif } switch(data_type){ case t_ONEBITPERPIXEL: nbyte = sizeof(UCHAR)*(nx/BITPERCHAR+(nx%BITPERWORD ? 4 : 0))*ny*nz; /* GLOUP 2006 CH */ break; case t_RGB: /* `bug': we do not handle this type, except for I */ /* nz is set to 3 (one color per plane) */ nz=3; case t_FOURBITPERPIXEL: /* `bug': we do not handle this type, except for I/O */ /* nbyte = ny*(nx/2+(nx%2))*sizeof(UCHAR); */ /* -> dummy type */ case t_TIFFONEBITPERPIXEL: /* `bug': we do not handle this type, except for I/O */ /* -> dummy type */ case t_UCHAR: nbyte = sizeof(UCHAR)*(mia_size_t)nx*ny*nz; break; case t_USHORT: nbyte = sizeof(USHORT)*(mia_size_t)nx*ny*nz; break; case t_SHORT: nbyte = sizeof(SHORT)*(mia_size_t)nx*ny*nz; break; case t_UINT32: nbyte = sizeof(UINT32)*(mia_size_t)nx*ny*nz; break; case t_INT32: nbyte = sizeof(INT32)*(mia_size_t)nx*ny*nz; break; case t_UINT64: nbyte = sizeof(UINT64)*(mia_size_t)nx*ny*nz; break; case t_INT64: nbyte = sizeof(INT64)*(mia_size_t)nx*ny*nz; break; case t_FLOAT: nbyte = sizeof(MIALFLOAT)*(mia_size_t)nx*ny*nz; break; case t_DOUBLE: nbyte = sizeof(DOUBLE)*(mia_size_t)nx*ny*nz; break; case t_PTR: nbyte = sizeof(void *)*(mia_size_t)nx*ny*nz; break; default: (void)sprintf(buf,"create_image(data_type=%d, nx=%ld, ny=%d, nz=%d): \ invalid data type\n", data_type, nx, ny, nz); errputstr(buf); free((char *)im); return(NULL); } if (nbyte%sizeof(long int)) /* pad for word size */ nbyte+=sizeof(long int); #if (defined(XLISP)) /* always call xlisp garbage collector (2004-12-6) */ gc(); #endif p = (char *)calloc(nbyte, sizeof(char)); if (p == NULL){ #if (defined(XLISP)) xmem(); gc(); xmem(); printf("nbyte=%lu\n", nbyte); p = (char *)calloc(nbyte, sizeof(char)); if (p == NULL){ (void)sprintf(buf,"ERROR in create_image(data_type=%d, nx=%ld, ny=%d, nz=%d) \ not enough memory (after call to garbage collector) \n", \ data_type, nx, ny, nz); errputstr(buf); xmem(); free((char *)im); return(NULL); } memset((void *) p, 0, nbyte * sizeof(char)); #else (void)sprintf(buf,"ERROR in create_image(data_type=%d, nx=%ld, ny=%d, nz=%d) \ not enough memory\n", data_type, nx, ny, nz); errputstr(buf); free((char *)im); return(NULL); #endif } SetImDataType(im, data_type); SetImNByte(im,nbyte); SetImPtr(im,p); SetImNx(im,nx); SetImNy(im,ny); SetImNz(im,nz); return(im); } /** free an image and its associated memory used to stored the pixel values @param im IMAGE pointer @return void */ void free_image(IMAGE *im) { void *p; // printf("message: entering free_image()\n"); #ifdef DMALLOC malloc_debug(2); (void)sprintf(buf,"malloc_debug returns %d in free_image\n",malloc_debug()); errputstr(buf); #endif if (im != NULL){ SetImNByte(im, 0); p = (void *)GetImPtr(im); if (p != NULL) free((void *)p); p = (void *)GetImLut(im); if (p != NULL) free((void *)p); free((void *)im); } else{ (void)sprintf(buf,"free_image(): Trying to free a freed image ..."); errputstr(buf); } } /** free the LUT associated with an IMAGE @param im IMAGE pointer */ void free_lut(IMAGE *im) { char *p; if (im != NULL){ p = (char *)GetImLut(im); if (p != NULL){ free((char *)p); SetImLut(im, NULL); } else{ (void)sprintf(buf,"free_lut(): Trying to free a LUT already freed ..."); errputstr(buf); } } else{ (void)sprintf(buf,"free_lut(): Trying to free the LUT of a freed image ..."); errputstr(buf); } } /** * returns the number of bits used to store an individual pixel, -1 on failure. * @param im IMAGE pointer * @return integer holding number of bits used to store a pixel, -1 on failure */ int GetImBitPerPixel(IMAGE *im) { switch (GetImDataType(im)){ case t_TIFFONEBITPERPIXEL: case t_ONEBITPERPIXEL: return(1); break; case t_FOURBITPERPIXEL: return(4); break; case t_UCHAR: return(BITPERCHAR); break; case t_USHORT: case t_SHORT: return(BITPERSHORT); break; case t_UINT32: case t_INT32: return(BITPERINT32); break; case t_UINT64: case t_INT64: return(BITPERINT64); break; case t_FLOAT: return(BITPERFLOAT); break; case t_DOUBLE: return(BITPERDOUBLE); break; case t_RGB: return(BITPERBAND); break; default: (void)sprintf(buf,"GetImBitPerPixel(im): invalid pixel type\n"); errputstr(buf); return(-1); } } /** print in stdout the values of the fields of the given IMAGE @param im IMAGE pointer @return void */ ERROR_TYPE iminfo(IMAGE *im) { G_TYPE *pg; unsigned short int *plut; int maxi; IMAGE *imhst=NULL; HST1D_TYPE *phst; int i; #ifdef XLDEBUG (void)sprintf(buf,"Image structure pointer\t=\t%p\n",im); stdputstr(buf); (void)sprintf(buf,"Pointer to image pixels\t=\t%p\n",GetImPtr(im)); stdputstr(buf); #endif /* XLDEBUG */ (void)sprintf(buf,"Image data type\t\t=\t%d\n",GetImDataType(im)); stdputstr(buf); pg = min_max(im); if (pg == NULL){ (void)sprintf(buf,"Unable to compute min/max image values\n"); errputstr(buf); maxi = -1; /* make sure it won't be used later */ } else{ (void)sprintf(buf,"Minimum image value\t=\t"); stdputstr(buf); (void)fprintfgenericnum(pg[0],GetImDataType(im)); (void)sprintf(buf,"Maximum image value\t=\t"); stdputstr(buf); (void)fprintfgenericnum(pg[1],GetImDataType(im)); maxi = (int)pg[1].uc_val; free((char *)pg); } (void)sprintf(buf,"Image size in x\t\t=\t%ld\n",GetImNx(im)); stdputstr(buf); (void)sprintf(buf,"Image size in y\t\t=\t%ld\n",GetImNy(im)); stdputstr(buf); (void)sprintf(buf,"Image size in z\t\t=\t%ld\n",GetImNz(im)); stdputstr(buf); (void)sprintf(buf,"Number of bytes\t\t=\t%ld\n",GetImNByte(im)); stdputstr(buf); plut = (unsigned short int *)GetImLut(im); if (plut != NULL){ imhst = histo1d(im); if (imhst != NULL){ (void)sprintf(buf,"ColorMap:\n"); stdputstr(buf); phst = (HST1D_TYPE *)GetImPtr(imhst); if (GetImDataType(im)==t_FOURBITPERPIXEL){ for (i=0; i<=maxi; i++){ if (phst[i]!=0){ (void)sprintf(buf,"R[%3d]= %3d\t G[%3d]= %3d\t B[%3d]= %3d\n",i, (int)plut[i], i, (int)plut[i+16],i , (int)plut[i+32]); stdputstr(buf); } } } else if (GetImDataType(im)==t_UCHAR){ for (i=0; i<=maxi; i++){ if (phst[i] != 0){ (void)sprintf(buf,"R[%3d]= %3d\t G[%3d]= %3d\t B[%3d]= %3d\n",i, (int)plut[i]>>8, i, (int)plut[i+256]>>8,i , (int)plut[i+512]>>8); stdputstr(buf); } } } free_image(imhst); } } return(NO_ERROR); } /*! generate a physical copy of an IMAGE @param im IMAGE pointer @return IMAGE pointer on success, NULL otherwise */ IMAGE *copy_image(IMAGE *im) { IMAGE *imout; int i; /* UCHAR *pim, *pimout; */ unsigned short int *plut; #ifdef DMALLOC malloc_debug(2); #endif imout = create_image(GetImDataType(im),GetImNx(im),GetImNy(im),(size_t) GetImNz(im)); if (imout != NULL){ /* pimout = (UCHAR *)GetImPtr(imout); pim = (UCHAR *)GetImPtr(im); */ memcpy((void *)GetImPtr(imout), (void *)GetImPtr(im), GetImNByte(im)); /* for (i=GetImNByte(im); i > 0; i--) *pimout++= *pim++; */ if (GetImLut(im) != NULL){ /* possible bug ... should be rewritten */ plut = (unsigned short int *)malloc(3*256*sizeof(short)); if (plut!=NULL){ SetImLut(imout,plut); for (i=0; i<768; i++) plut[i]=im->lut[i]; } } } #ifdef DMALLOC (void)sprintf(buf,"malloc_debug returns %d in copy_image\n",malloc_debug()); errputstr(buf); #endif return(imout); } /*************************************************************************/ IMBLOB *create_blob(LBL_TYPE n) { IMBLOB *blob; blob= (IMBLOB *)calloc((size_t)n, sizeof(IMBLOB)); if (blob == NULL){ #if (defined(XLISP)) gc(); blob= (IMBLOB *)calloc((size_t)n, sizeof(IMBLOB)); if (blob == NULL){ (void)sprintf(buf,"ERROR in create_blob(n): not enough memory\n"); errputstr(buf); } return(blob); #else (void)sprintf(buf,"ERROR in create_blob(n): not enough memory\n"); errputstr(buf); #endif } return(blob); } /** create a LUT and associate it with the input IMAGE. A LUT consists of 768 values indicating the RGB value of any byte pixel value (the codes are interleaved by band in the RGB order). @param im IMAGE pointer @return NO_ERROR on success, ERROR otherwise */ ERROR_TYPE create_lut(IMAGE *im) { unsigned short int * out_lut; int i; out_lut = GetImLut(im); if(out_lut == NULL){ out_lut = (unsigned short int *)malloc(3*256*sizeof(short)); } else{ (void)sprintf(buf,"WARNING in create_lut: image has already a LUT\n"); errputstr(buf); return(NO_ERROR); } if(out_lut == NULL){ (void)sprintf(buf,"ERROR in create_lut not enough memory to create new lut\n"); errputstr(buf); return(ERROR); } SetImLut(im, out_lut); for (i=0; i<768; i++) out_lut[i]=(i%256)<<8; return(NO_ERROR); } /** copy the LUT associated with the first IMAGE to the LUT associated with the second IMAGE @param im1 IMAGE pointer @param im2 IMAGE pointer @return NO_ERROR on success, ERROR otherwise */ ERROR_TYPE copy_lut(IMAGE *im1, IMAGE *im2) { unsigned short int *out_lut; int n=768; /* RGB LUTs have 256 entries per band */ int i; if(GetImLut(im2) == NULL){ (void)sprintf(buf,"ERROR in copy_lut no lut in input image\n"); errputstr(buf); return(ERROR); } out_lut = GetImLut(im1); if(out_lut == NULL){ out_lut = (unsigned short int *)malloc(n*sizeof(short)); } else{ free(out_lut); out_lut = (unsigned short int *)malloc(n*sizeof(short)); } if(out_lut == NULL){ (void)sprintf(buf,"ERROR in copy_lut not enough memory to create new lut\n"); errputstr(buf); return(ERROR); } SetImLut(im1, out_lut); for (i=0; ilut[i]; return(NO_ERROR); } /** set the pixel value of im at position offset to the value encapsulated in g @param im IMAGE pointer @param offset int for offset from origin (0 for 1st pixel) @param g G_TYPE for pixel value @return NO_ERROR on success, ERROR otherwise */ ERROR_TYPE setpixval(IMAGE *im, unsigned long offset, G_TYPE g) { switch(GetImDataType(im)){ case t_UCHAR: *((UCHAR *) GetImPtr(im) + offset) = g.uc_val; return NO_ERROR; case t_USHORT: *((USHORT *) GetImPtr(im) + offset) = g.us_val; return NO_ERROR; case t_SHORT: *((SHORT *) GetImPtr(im) + offset) = g.s_val; return NO_ERROR; case t_INT32: *((INT32 *) GetImPtr(im) + offset) = g.i32_val; return NO_ERROR; case t_UINT32: *((UINT32 *) GetImPtr(im) + offset) = g.u32_val; return NO_ERROR; case t_INT64: *((INT64 *) GetImPtr(im) + offset) = g.i64_val; return NO_ERROR; case t_UINT64: *((UINT64 *) GetImPtr(im) + offset) = g.u64_val; return NO_ERROR; case t_FLOAT: *((MIALFLOAT *) GetImPtr(im) + offset) = g.f_val; return NO_ERROR; case t_DOUBLE: *((DOUBLE *) GetImPtr(im) + offset) = g.d_val; return NO_ERROR; default: (void)sprintf(buf,"setpixval(): invalid pixel type=%d\n", GetImDataType(im)); errputstr(buf); } return ERROR; } /** get the pixel value of im at position offset @param im IMAGE pointer @param offset int for offset from origin (0 for 1st pixel) @return G_TYPE for pixel value */ G_TYPE getpixval(IMAGE *im, unsigned long offset) { G_TYPE g; switch(GetImDataType(im)){ case t_UCHAR: g.uc_val= *((UCHAR *) GetImPtr(im) + offset); break; case t_USHORT: g.us_val= *((USHORT *) GetImPtr(im) + offset); break; case t_SHORT: g.s_val= *((SHORT *) GetImPtr(im) + offset); break; case t_INT32: g.i32_val= *((INT32 *) GetImPtr(im) + offset); break; case t_UINT32: g.u32_val= *((UINT32 *) GetImPtr(im) + offset); break; case t_INT64: g.i64_val= *((INT64 *) GetImPtr(im) + offset); break; case t_UINT64: g.u64_val= *((UINT64 *) GetImPtr(im) + offset); break; case t_FLOAT: g.f_val= *((MIALFLOAT *) GetImPtr(im) + offset); break; case t_DOUBLE: g.d_val= *((DOUBLE *) GetImPtr(im) + offset); break; default: (void)sprintf(buf,"getpixval(): invalid pixel type=%d\n", GetImDataType(im)); errputstr(buf); } return g; } #include "uc_def.h" ERROR_TYPE uc_FindPixWithVal(IMAGE *im, PIX_TYPE val, unsigned long int *ofs) { PIX_TYPE *p, *pend; p=(PIX_TYPE *)GetImPtr(im); pend=p+GetImNPix(im); for(;pGetImNPix(imroi)) || (GetImDataType(imroi) != t_UCHAR)){ (void)sprintf(buf,"arraytoim(IMAGE *im, IMAGE *imroi): im must not have more pixels than imroi and imroi must be of type UCHAR\n"); errputstr(buf); return NULL; } switch(GetImDataType(im)){ case t_UCHAR: return(uc_arraytoim(im, imroi)); break; case t_USHORT: return(us_arraytoim(im, imroi)); break; case t_INT32: case t_UINT32: case t_FLOAT: return(g32_arraytoim(im, imroi)); break; default: (void)sprintf(buf, "error in arraytoim(): \ undefined image data type\n"); errputstr(buf); return(NULL); } return(NULL); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "s_def.h" ERROR_TYPE s_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "s_undef.h" #include "us_def.h" ERROR_TYPE us_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "i32_undef.h" #include "u32_def.h" ERROR_TYPE u32_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6u",p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "u32_undef.h" #include "i64_def.h" ERROR_TYPE i64_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6ld",(long int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "i64_undef.h" #include "u64_def.h" ERROR_TYPE u64_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %4d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%6.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6lu",(long unsigned int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "u64_undef.h" #include "f_def.h" ERROR_TYPE f_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf,"%9d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%10.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "f_undef.h" #include "d_def.h" ERROR_TYPE d_dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { int y1, y2, x1, x2; int i, j; int nx, ny, nz; PIX_TYPE *p; p=(PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); x = MIN(abs(x),nx-1); y = MIN(abs(y),ny-1); z = MIN(abs(z),nz-1); x1 = x-dx/2; if (x1<0) x1=0; y1 = y-dy/2; if (y1<0) y1=0; x2 = x+dx/2; if (x2>=nx) x2=nx-1; y2 = y+dy/2; if (y2>=ny) y2=ny-1; (void)sprintf(buf,"z=%4d ", z); stdputstr(buf); for (i=x1; i<=x2; i++){ (void)sprintf(buf," %9d|",i); stdputstr(buf); } (void)sprintf(buf,"\n"); stdputstr(buf); for (i=y1; i<=y2; i++){ (void)sprintf(buf,"|%4d|",i); stdputstr(buf); for (j=x1; j<=x2; j++){ #if FLOATING (void)sprintf(buf,"%10.3f",(float)p[z*nx*ny+i*nx+j]); stdputstr(buf); #else (void)sprintf(buf,"%6d",(int)p[z*nx*ny+i*nx+j]); stdputstr(buf); #endif } (void)sprintf(buf,"\n"); stdputstr(buf); } return(NO_ERROR); } #include "d_undef.h" ERROR_TYPE dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_dumpxyz(im, x, y, z, dx, dy)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_dumpxyz(im, x, y, z, dx, dy)); break; #endif case t_SHORT: return(s_dumpxyz(im, x, y, z, dx, dy)); break; case t_USHORT: return(us_dumpxyz(im, x, y, z, dx, dy)); break; case t_INT32: return(i32_dumpxyz(im, x, y, z, dx, dy)); break; case t_UINT32: return(u32_dumpxyz(im, x, y, z, dx, dy)); break; case t_INT64: return(i64_dumpxyz(im, x, y, z, dx, dy)); break; case t_UINT64: return(u64_dumpxyz(im, x, y, z, dx, dy)); break; case t_FLOAT: return(f_dumpxyz(im, x, y, z, dx, dy)); break; case t_DOUBLE: return(d_dumpxyz(im, x, y, z, dx, dy)); break; default: (void) sprintf(buf, "dumpxyz(): invalid pixel type\n"); errputstr(buf); return ERROR; } return NO_ERROR; } /**@}*/ jeolib-miallib-1.1.6/core/c/imio.c000066400000000000000000001241511467232417700166660ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* ** Author: Pierre Soille 1988-2006 */ #include #include #include #include //#ifndef UNIX //#include "bytesex.h" /* only for linux ... */ //#endif //#include "/home/soillpi/coolsoft/tiff-4.0.0beta7/libtiff/tiffiop.h" /* added p in name for bigtiff 20110513 */ #include //#include "xtiffio.h" /* 2005-10-24 */ // #include "geotiff.h" /* 2005-10-24 */ /* #include "banner.h" /\* 2007-12-10 *\/ */ #include "miallib.h" #include "imio.h" /* #define BYTE_ORDER 1234 */ //#define TIFF_BIGTIFF 0x80000 extern IMAGE *deinterleave(IMAGE *); /** @defgroup group_io I/O operations * Functions dealing with image I/0. * @{ */ /* * * * getCrtTimeString: generates a string with the current date and time. * example: 2004_06_24_18_54 for 24th of June 2004 at 18.54 o'clock * * Parameters: * * timeString pointer to a char array in which the string is stored * * Return values: * * time string pointer to the input char array if everything was ok. * */ char *getCrtTimeString(char *timeString){ char year[5]; char month[3]; char day[3]; char hour[3]; char minute[3]; char second[3]; // YYYY:MM:DD HH:MM:SS time_t tp; time(&tp); strftime(year, 5, "%Y", localtime(&tp)); strftime(month, 3, "%m", localtime(&tp)); strftime(day, 3, "%d", localtime(&tp)); strftime(hour, 3, "%H", localtime(&tp)); strftime(minute, 3, "%M", localtime(&tp)); strftime(second, 3, "%S", localtime(&tp)); strcpy(timeString,year); strcat(timeString, ":"); strcat(timeString,month); strcat(timeString, ":"); strcat(timeString,day); strcat(timeString, " "); strcat(timeString,hour); strcat(timeString, ":"); strcat(timeString,minute); strcat(timeString, ":"); strcat(timeString,second); // printf("%s \n", timeString); return timeString; } /*************************************************************************/ /* */ ERROR_TYPE read_image_data(FILE *fp, IMAGE *im, int pc) { unsigned long int i, npix, nelem; int j, k, y, z, nx, ny, nz, nbpl, nplb, bpp; UCHAR data, temp, *p; p = (UCHAR *)GetImPtr(im); nx = GetImNx(im); npix = GetImNPix(im); switch(GetImDataType(im)){ case t_TIFFONEBITPERPIXEL: /* assumes 1 x-y plane */ /* padding for 8 bits as in TIFF files */ /* t_TIFFONEBITPERPIXEL just for I/O */ /* the image is read into a t_UCHAR image */ /* note: image_create() takes this feature into account */ SetImDataType(im,t_UCHAR); /* force to t_UCHAR */ nbpl = nx/BITPERCHAR; /* nbr of bytes per line */ nplb = nx%BITPERCHAR; /* nbr of pixels in last byte */ for (k=0; k>4; p[(2*i)+1+k] = (data <<= 4)>>4; } if (nplb){ if ((fread((char *)&data, (int)1, (int)1, fp)) != 1){ (void)sprintf(buf,"ERROR in read_image_data(): \ unable to read image data block\n"); errputstr(buf); return(ERROR); } p[(2*i)+k] = data>>4; } } return(NO_ERROR); case t_UCHAR: case t_USHORT: /* BUG LITTLE vs BIG ENDIAN not taken into account */ case t_SHORT: /* BUG LITTLE vs BIG ENDIAN not taken into account */ case t_UINT32: /* BUG LITTLE vs BIG ENDIAN not taken into account */ case t_INT32: /* BUG LITTLE vs BIG ENDIAN not taken into account */ case t_FLOAT: /* BUG LITTLE vs BIG ENDIAN not taken into account */ case t_DOUBLE: /* BUG LITTLE vs BIG ENDIAN not taken into account */ break; default: (void)sprintf(buf,"ERROR in read_image_data(): \ invalid data type\n"); errputstr(buf); return(ERROR); } if (pc==PLANARCONFIG_CONTIG && GetImNz(im)>1){ /* interleaved x-y plane strorage (BIP) */ nelem = GetImNPixPerPlane(im); p = (UCHAR *)GetImPtr(im); nz=GetImNz(im); bpp=GetImBitPerPixel(im)/8; for (i=0; i1){ /* interleaved by line (BIL) */ nelem = GetImNPixPerPlane(im); p = (UCHAR *)GetImPtr(im); nx=GetImNx(im); ny=GetImNy(im); nz=GetImNz(im); bpp=GetImBitPerPixel(im)/8; for(y=0;y3) { printf("WARNING: unexpected TIFFTAG_SAMPLEFORMAT=%d!!! trying with default value 1!!!\n", sf); sf=1; } if (spp>1) TIFFGetField(tiffp, TIFFTAG_PLANARCONFIG, &pc); if ( (bitpp == BITPERCHAR) && (sf==1) ) data_type = t_UCHAR; else if (bitpp == BITPERSHORT){ if (sf==1) data_type = t_USHORT; else if (sf==2) data_type = t_SHORT; } else if ( (bitpp == BITPERINT32) && (sf==3) ) data_type = t_FLOAT; else if ( (bitpp == BITPERINT32) && (sf==1) ) data_type = t_UINT32; else if ( (bitpp == BITPERINT32) && (sf==2) ) data_type = t_INT32; else if (bitpp == BITPERDOUBLE) data_type = t_DOUBLE; if (data_type!=t_UNSUPPORTED){ TIFFGetField(tiffp, TIFFTAG_COMPRESSION, &ctype); nstrip = TIFFNumberOfStrips(tiffp); // printf("data_type=%d nstrip=%d\n", data_type, nstrip); TIFFGetField(tiffp, TIFFTAG_ROWSPERSTRIP, &rps); /* if ((nstrip != 1 && ctype==1) || ctype==5){*/ if (nstrip != 1 || ctype != 1){ #ifdef XLDEBUG (void)sprintf(buf,"TIFFTAG_ROWSPERSTRIP=%d\n", (int)rps); errputstr(buf); (void)sprintf(buf,"nstrip=%d\n", (int)nstrip); errputstr(buf); (void)sprintf(buf,"read_image(): number of strips exceeds 1 or compression, \ I shall try to read it using TIFFReadEncodedStrip\n"); errputstr(buf); #endif im = create_image(data_type, nx, ny, spp); if (im == NULL){ (void)sprintf(buf,"read_image(): not enough memory!\n"); errputstr(buf); TIFFClose(tiffp); return(NULL); } for (strip = 0; strip < nstrip-1; strip++){ nbyte=TIFFReadEncodedStrip(tiffp, strip, GetImPtr(im)+bread, (tsize_t) -1); bread+=nbyte; if (nbyte==-1){ (void)sprintf(buf,"read_image(): problem when reading strip number %d\n", (int)strip); errputstr(buf); TIFFClose(tiffp); return(NULL); } } /* read last strip (possibly not containing a full set of rows!)*/ if (bread1) && (pc==1)){ /* deinterleave */ imtmp= deinterleave(im); if (imtmp == NULL){ (void)sprintf(buf,"warning: read_image(): not enough memory for deinterleaving!\n"); errputstr(buf); return im; } free_image(im); return imtmp; } return im; } } TIFFGetField(tiffp, TIFFTAG_STRIPOFFSETS, &s_o_t); fsot = (long)*s_o_t; TIFFGetField(tiffp, TIFFTAG_BITSPERSAMPLE, &bitpp); red = (uint16_t *)malloc(1<>8); ny = ((kiff_head[4]&0xFF)<<8)|(kiff_head[4]>>8); (void) fclose(fp); return(read_all(fn, nx, ny, 1, t_UCHAR, 128, 1)); } else{ (void)sprintf(buf,"read_file(): unable to read %s on disk\n", fn); errputstr(buf); im = NULL; } } else{ /* it is a VISILOG file */ nx = visi[1]; ny = visi[2]; nz = visi[3]; bitpp = visi[9]; if (bitpp == 8) data_type = t_UCHAR; else if (bitpp == 16) data_type = t_USHORT; else if (bitpp == 32) data_type = t_INT32; (void) fclose(fp); return(read_all(fn, nx, ny, nz, data_type, 76, 1)); } (void) fclose(fp); return(im); } /*****************************************************************************/ ERROR_TYPE write_image_data(FILE *fp, IMAGE *im, int pc) { unsigned long int nelem, i, y, z; UCHAR *p, *plast; long int bpp, nx, ny, nz = GetImNz(im); switch (GetImDataType(im)){ case t_TIFFONEBITPERPIXEL: case t_ONEBITPERPIXEL: case t_FOURBITPERPIXEL: case t_UCHAR: case t_USHORT: case t_SHORT: case t_UINT32: case t_INT32: case t_FLOAT: case t_DOUBLE: if (GetImNz(im)>1){ if (pc==PLANARCONFIG_CONTIG){ /* bip model (band interleaved by pixel) TIFF default */ /* interleave x-y planes by pixel (bip) */ bpp=GetImBitPerPixel(im)/8; nelem=GetImNPixPerPlane(im); p=(UCHAR *)GetImPtr(im); for (i=0; i INT32 */ tag_info[LENGTH].data_type = 4; tag_info[BPS].data_type = 3; tag_info[PMI].data_type = 3; tag_info[NAME].data_type = 2; /* 2 ==> 8-bits ASCII codes */ tag_info[DESC].data_type = 2; /* 2 ==> 8-bits ASCII codes */ tag_info[SOT].data_type = 4; tag_info[SPP].data_type = 3; tag_info[SBC].data_type = 4; /* 4 ==> INT32 */ tag_info[XR].data_type = 5; /* 5 ==> RATIONAL */ tag_info[YR].data_type = 5; /* 5 ==> RATIONAL */ tag_info[ColorMap].data_type = 3; /* Length initialisation */ tag_info[WIDTH].length = 1; tag_info[LENGTH].length = 1; tag_info[BPS].length = 1; tag_info[PMI].length = 1; /* 3 for Palette Color */ tag_info[NAME].length = 32; /* Document name */ tag_info[DESC].length = 256; /* Document information */ tag_info[SOT].length = 1; tag_info[SPP].length = 1; tag_info[SBC].length = 1; tag_info[XR].length = 1; tag_info[YR].length = 1; tag_info[ColorMap].length = 3*(1 << GetImBitPerPixel(im)); /* Values fitting in tag initialisation */ #if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ tag_info[WIDTH].ValOrPoint = GetImNx(im); tag_info[LENGTH].ValOrPoint = GetImNy(im); tag_info[BPS].ValOrPoint = (short)GetImBitPerPixel(im); tag_info[PMI].ValOrPoint = (short)pmi; tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+16+tag_info[ColorMap].length*2; tag_info[SPP].ValOrPoint = (short)spp; tag_info[SBC].ValOrPoint = GetImNByte(im); /* Offset of values not fitting in tag initialisation */ tag_info[NAME].ValOrPoint = 10+nbr_tags*12+4; tag_info[DESC].ValOrPoint = 10+nbr_tags*12+4+32; tag_info[XR].ValOrPoint = 10+nbr_tags*12+4+32+256; tag_info[YR].ValOrPoint = 10+nbr_tags*12+4+32+256+8; tag_info[ColorMap].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8; #else /* big-endian */ tag_info[WIDTH].ValOrPoint = GetImNx(im); tag_info[LENGTH].ValOrPoint = GetImNy(im); tag_info[BPS].ValOrPoint = GetImBitPerPixel(im)<<16; tag_info[PMI].ValOrPoint = pmi<<16; tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+16+tag_info[ColorMap].length*2; tag_info[SPP].ValOrPoint = spp<<16; tag_info[SBC].ValOrPoint = GetImNByte(im); if (GetImNz(im)!=1 && GetImDataType(im)!=t_RGB) tag_info[N_PLANE].ValOrPoint = GetImNz(im)<<16; /* Offset of values not fitting in tag initialisation */ tag_info[NAME].ValOrPoint = 10+nbr_tags*12+4; tag_info[DESC].ValOrPoint = 10+nbr_tags*12+4+32; tag_info[XR].ValOrPoint = 10+nbr_tags*12+4+32+256; tag_info[YR].ValOrPoint = 10+nbr_tags*12+4+32+256+8; tag_info[ColorMap].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8; #endif /* big-endian */ /* Open output file */ if ((fp = fopen(fn, "wb")) == NULL){ (void)sprintf(buf, "write_tiff(): unable to open output file\n"); errputstr(buf); if (swapflag) free_image(im); return(ERROR); } /* Write header */ (void) fwrite((char *)&tiff_head, sizeof(tiff_head), 1, fp); (void) fwrite((char *)&nbr_tags, 2, 1, fp); (void) fwrite((char *)tag_info, 12*nbr_tags, 1, fp); free((char *)tag_info); (void) fwrite((char *)&ptr_dir2, 4, 1, fp); (void) fwrite((char *)doc_name, sizeof(doc_name), 1, fp); (void) fwrite((char *)doc_info, sizeof(doc_info), 1, fp); (void) fwrite((char *)&xr_n, 4, 1, fp); (void) fwrite((char *)&xr_d, 4, 1, fp); (void) fwrite((char *)&yr_n, 4, 1, fp); (void) fwrite((char *)&yr_d, 4, 1, fp); (void) fwrite((void *)GetImLut(im), 2, (1< INT32 */ tag_info[LENGTH].data_type = 4; tag_info[BPS].data_type = 3; /* 3 ==> SHORT */ tag_info[PMI].data_type = 3; tag_info[NAME].data_type = 2; /* 2 ==> 8-bits ASCII codes */ tag_info[DESC].data_type = 2; tag_info[SOT].data_type = 4; tag_info[SPP].data_type = 3; tag_info[SBC].data_type = 4; tag_info[XR].data_type = 5; /* 5 ==> RATIONAL */ tag_info[YR].data_type = 5; tag_info[SF].data_type = 3; /* if (GetImNz(im)!=1 && GetImDataType(im)!=t_RGB) */ /* tag_info[N_PLANE].data_type = 3; */ /* Length initialisation */ tag_info[WIDTH].length = 1; tag_info[LENGTH].length = 1; tag_info[BPS].length = 1; tag_info[PMI].length = 1; tag_info[NAME].length = 32; /* Document name */ tag_info[DESC].length = 256; /* Document information */ tag_info[SOT].length = 1; tag_info[SPP].length = 1; tag_info[SBC].length = 1; tag_info[XR].length = 1; tag_info[YR].length = 1; /* if (GetImNz(im)!=1 && GetImDataType(im)!=t_RGB) */ /* tag_info[N_PLANE].length = 1; */ /* take minimum and maximum image values into account */ nbyte=(GetImBitPerPixel(im)/8) * GetImNPix(im); //GetImNByte(im); if (GetImDataType(im)==t_UCHAR){ pg = min_max(im); if (pg != NULL){ uc_maxi = pg[1].uc_val; free(pg); if (uc_maxi < 2){ /* printf("converting to 1 bit per pixel\n"); */ imtmp = to_tiff1bitpp(im); if (imtmp == NULL){ free((char *)tag_info); return(ERROR); } im = imtmp; swapflag = 1; nbyte=GetImNy(im)*(GetImNx(im)/8+(GetImNx(im)%8 ? 1: 0))*sizeof(UCHAR); /* printf("nbyte=%lu\n", nbyte); */ } else if (uc_maxi < 16){ /* printf("converting to 4 bits per pixel\n"); */ imtmp = to_tiff4bitpp(im); if (imtmp == NULL){ free((char *)tag_info); return(ERROR); } im = imtmp; swapflag = 1; nbyte=GetImNy(im)*(GetImNx(im)/2+(GetImNx(im)%2))*sizeof(UCHAR); /* printf("nbyte=%lu\n", nbyte); */ } } } /* if (GetImDataType(im)==t_RGB){ /\* full color image *\/ */ /* tag_info[BPS].length = GetImNz(im); */ /* pmi=2; */ /* spp=GetImNz(im); /\* may be more for multispectral images *\/ */ /* } */ if (GetImNz(im)>1){ /* multichannel or 3-D image */ tag_info[BPS].length = GetImNz(im); pmi=2; spp=GetImNz(im); } tag_info[SF].length = spp; switch (GetImDataType(im)){ /* set SampleFormat field value */ case t_UCHAR: case t_USHORT: case t_UINT32: case t_RGB: sf=1; /* unsigned integer data */ break; case t_SHORT: case t_INT32: sf=2; /* 2's complement signed integer data */ break; case t_FLOAT: case t_DOUBLE: sf=3; /* IEEE floating point data */ break; default: sf=4; /* undefined data format */ } /* Values fitting in tag initialisation */ #if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ tag_info[WIDTH].ValOrPoint = GetImNx(im); tag_info[LENGTH].ValOrPoint = GetImNy(im); tag_info[BPS].ValOrPoint = GetImBitPerPixel(im)<<16; tag_info[PMI].ValOrPoint = pmi<<16; tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+16; tag_info[SPP].ValOrPoint = spp<<16; tag_info[SF].ValOrPoint = sf<<16; tag_info[SBC].ValOrPoint = nbyte; //GetImNByte(im); //GetImBitPerPixel(im)/8 * GetImNPix(im); /* if (GetImNz(im)!=1 && GetImDataType(im)!=t_RGB) */ /* tag_info[N_PLANE].ValOrPoint = GetImNz(im)<<16; */ /* Offset of values not fitting in tag initialisation */ tag_info[NAME].ValOrPoint = 10+nbr_tags*12+4; tag_info[DESC].ValOrPoint = 10+nbr_tags*12+4+32; tag_info[XR].ValOrPoint = 10+nbr_tags*12+4+32+256; tag_info[YR].ValOrPoint = 10+nbr_tags*12+4+32+256+8; if (pmi==2){ /* reset tag 2 and 6 */ tag_info[BPS].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8; tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8+GetImNz(im)*2; } if (spp>1){ tag_info[SF].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8+GetImNz(im)*2; tag_info[SOT].ValOrPoint += GetImNz(im)*2; } #elif __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ tag_info[WIDTH].ValOrPoint = GetImNx(im); tag_info[LENGTH].ValOrPoint = GetImNy(im); tag_info[BPS].ValOrPoint = (short)GetImBitPerPixel(im); tag_info[PMI].ValOrPoint = (short)pmi; tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+16; tag_info[SPP].ValOrPoint = (short)spp; tag_info[SF].ValOrPoint = (short)sf; tag_info[SBC].ValOrPoint = nbyte; //GetImNByte(im); //GetImBitPerPixel(im)/8 * GetImNPix(im); /* if (GetImNz(im)!=1 && GetImDataType(im)!=t_RGB) */ /* tag_info[N_PLANE].ValOrPoint = (short)GetImNz(im); */ /* Offset of values not fitting in tag initialisation */ tag_info[NAME].ValOrPoint = 10+nbr_tags*12+4; tag_info[DESC].ValOrPoint = 10+nbr_tags*12+4+32; tag_info[XR].ValOrPoint = 10+nbr_tags*12+4+32+256; tag_info[YR].ValOrPoint = 10+nbr_tags*12+4+32+256+8; if (pmi==2){ /* reset tag 2 and 6 */ tag_info[BPS].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8; /* reset */ tag_info[SOT].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8+GetImNz(im)*2; } if (spp>1){ tag_info[SF].ValOrPoint = 10+nbr_tags*12+4+32+256+8+8+GetImNz(im)*2; tag_info[SOT].ValOrPoint += GetImNz(im)*2; } #else #error BYTE_ORDER must be either BIG_ENDIAN or LITTLE_ENDIAN #endif /* Open output file */ if ((fp = fopen(fn, "wb")) == NULL){ (void)sprintf(buf, "write_tiff(): unable to open output file\n"); errputstr(buf); if (swapflag) free_image(im); return(ERROR); } /* Write header */ (void) fwrite((char *)&tiff_head, sizeof(tiff_head), 1, fp); (void) fwrite((char *)&nbr_tags, 2, 1, fp); (void) fwrite((char *)tag_info, 12*nbr_tags, 1, fp); free((char *)tag_info); (void) fwrite((char *)&ptr_dir2, 4, 1, fp); (void) fwrite((char *)doc_name, sizeof(doc_name), 1, fp); (void) fwrite((char *)doc_info, sizeof(doc_info), 1, fp); (void) fwrite((char *)&xr_n, 4, 1, fp); (void) fwrite((char *)&xr_d, 4, 1, fp); (void) fwrite((char *)&yr_n, 4, 1, fp); (void) fwrite((char *)&yr_d, 4, 1, fp); if (pmi==2){ for (i=0;i1){ for (i=0;i UINT32_MAX ){ (void)printf("writetiffospl() message: output file %s will be a bigtiff file\n", fn); *mp++ = '8'; *mp = '\0'; } tif = TIFFOpen(fn, mode); if (tif==NULL){ (void)sprintf(buf,"writetiffospl(): unable to write %s on disk\n", fn); errputstr(buf); return ERROR; } TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, GetImBitPerPixel(im)); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, nz); if (nz > 1) TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE); else TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW); if ( GetImBitPerPixel(im) <= 16 ) TIFFSetField(tif, TIFFTAG_PREDICTOR, 2); /* PREDICTOR_HORIZONTAL = 2 */ if ( (GetImLut(im)!=NULL) && (GetImDataType(im)==t_UCHAR)){ lut=(USHORT *)GetImLut(im); TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, 3); if ( TIFFSetField(tif, TIFFTAG_COLORMAP, lut, lut+256, lut+512) != 1 ) (void)sprintf(buf,"writetiffospl(%s): error while setting colour map\n", fn); } else TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); switch (GetImDataType(im)){ /* set SampleFormat field value */ case t_UCHAR: case t_USHORT: case t_UINT32: sf=1; /* unsigned integer data */ break; case t_SHORT: case t_INT32: sf=2; /* two's complement signed integer data */ break; case t_FLOAT: case t_DOUBLE: sf=3; /* IEEE floating point data */ break; default:/* undefined data format */ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): undefined data format\n", fn); errputstr(buf); return ERROR; } TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sf); TIFFSetField(tif, TIFFTAG_DATETIME, getCrtTimeString(timeString)); TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, fn); #ifdef XLISP TIFFSetField(tif, TIFFTAG_SOFTWARE, "mialisp"); #endif #ifdef FSP TIFFSetField(tif, TIFFTAG_SOFTWARE, "mspa v2.0"); #endif TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, imdesc); lbuf=(void *)malloc(nx*bpp); if (lbuf==NULL){ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): not enough memory for line buffer\n", fn); errputstr(buf); return ERROR; } for(stripCount=0; stripCount1) TIFFGetField(tiffp, TIFFTAG_PLANARCONFIG, &pc); if ( (bitpp == BITPERCHAR) && (sf==1) ) fdata_type = t_UCHAR; else if ( (bitpp == BITPERINT32) && (sf==3) ) fdata_type = t_FLOAT; else if ( (bitpp == BITPERINT32) && (sf==1) ) fdata_type = t_UINT32; else if ( (bitpp == BITPERINT32) && (sf==2) ) fdata_type = t_INT32; else if (bitpp == BITPERDOUBLE) fdata_type = t_DOUBLE; if (fdata_type != t_UNSUPPORTED){ TIFFGetField(tiffp, TIFFTAG_COMPRESSION, &ctype); nstrip = TIFFNumberOfStrips(tiffp); TIFFGetField(tiffp, TIFFTAG_ROWSPERSTRIP, &rps); if ( (ctype != 1) && (nstrip == ny) && (fdata_type == t_UCHAR) ){ im = create_image(data_type, nx, ny, spp); if (im == NULL){ (void)sprintf(buf,"read_image(): not enough memory!\n"); errputstr(buf); TIFFClose(tiffp); return(NULL); } pim=(USHORT *)GetImPtr(im); lim = create_image(fdata_type, nx, 1, spp); if (lim == NULL){ (void)sprintf(buf,"read_image_to_type(): not enough memory for line buffer!\n"); errputstr(buf); TIFFClose(tiffp); return(NULL); } for (strip = 0; strip < nstrip-1; strip++){ nbyte=TIFFReadEncodedStrip(tiffp, strip, GetImPtr(lim), (tsize_t) -1); bread+=nbyte; if (nbyte==-1){ (void)sprintf(buf,"read_image(): problem when reading strip number %d\n", (int)strip); errputstr(buf); TIFFClose(tiffp); return(NULL); } plim=(UCHAR *)GetImPtr(lim); for (i=0;i1) && (pc==1)){ /* deinterleave */ imtmp= deinterleave(im); if (imtmp == NULL){ (void)sprintf(buf,"warning: read_image(): not enough memory for deinterleaving!\n"); errputstr(buf); return im; } free_image(im); return imtmp; } return im; } } (void)sprintf(buf,"warning: read_image_in_type(): unsupported data type!\n"); errputstr(buf); } return NULL; } /**@}*/ jeolib-miallib-1.1.6/core/c/imio.h000066400000000000000000000046351467232417700166770ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* processor specific definitions (see endian.h under linux */ #ifndef LITTLE_ENDIAN /* intel processors */ #define LITTLE_ENDIAN 1234 #endif #ifndef BIG_ENDIAN #define BIG_ENDIAN 4321 #endif /* ** TIFF structures. */ struct mytiff { short int byte_order; /* for little or big-endian */ short int version ; /* TIFF version*/ int ptr_dir1; /* Offset to first directory*/ }; struct tag { unsigned short int type; /*Type of considered tag*/ short int data_type; /*Data type to provide tag information*/ int length; /*Length of the information*/ int ValOrPoint; /*Value or pointer to information*/ }; enum tiff_tags {WIDTH, LENGTH, BPS, PMI, NAME, DESC, SOT, SPP, SBC, XR, YR, SF, N_PLANE, NBR_TAGS}; /* SF=SampleFormat added on 17-2-2004 */ #define ColorMap N_PLANE /* **VISILOG structure. */ struct visi { int magic; /*must be Ox6931*/ int gx; /*pixels per line*/ int gy; /*number of lines*/ int gz; /*number of planes per image(must be 1)*/ int rs0; /*reserved (must be 0)*/ int rs1; /*reserved (must be 0)*/ int grid; /*grid type (0 ==> rec, 1 ==> hex)*/ int rs2; /*reserved (must be 0)*/ int gcode; /*arithmetic type*/ int bstoc; /*bits per pixel*/ int rs3; /*reserved (must be 0)*/ int ox; /*X-origin*/ int oy; /*Y-origin*/ int oz; /*Z-origin (must be 1)*/ int rs4; /*reserved (must be 0)*/ int sizevisihead; /*visilog header size(must be 76)*/ int sizeuserhead; /*user header size(must be 0)*/ int rs5; /*reserved (must be 0)*/ int sizehead; /*total header size(must be 76)*/ }; jeolib-miallib-1.1.6/core/c/imio2.c000066400000000000000000001312441467232417700167510ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include #include /* for gethostname */ #include #ifndef UNIX // #include "bytesex.h" /* only for linux ... */ #include #endif #include "miallib.h" #include "imio.h" #include #include #include /* 2005-12-20 */ /* #include "banner.h" /\* 2007-12-10 *\/ */ #if (!defined(SEEK_CUR)) #define SEEK_CUR 1 #endif extern char *getCrtTimeString(char *timeString); extern int gethostname(char *name, size_t len); /* fix to prevent warning, include unistd.h not sufficient */ /** \addtogroup group_io * @{ */ /***********************************************************************/ /* start of patch to accomodate unofficial extended TIFFTAGS with initial suggestion from http://even.rouault.free.fr/services.html see also code of http://www.remotesensing.org/libtiff/addingtags.html First: 20130928 */ #define TIFFTAG_GDAL_METADATA 42112 #define TIFFTAG_GDAL_NODATA 42113 #define TIFFTAG_RPCCOEFFICIENT 50844 /************************************************************************/ /* GTiffTagExtender() */ /* */ /* Install tags specially known to GDAL. */ /************************************************************************/ static int GdalTiffTags_flag=0; static TIFFExtendProc _ParentExtender = NULL; static void GTiffTagExtender(TIFF *tif){ static const TIFFFieldInfo xtiffFieldInfo[] = { { TIFFTAG_GDAL_METADATA, -1,-1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, (char*) "GDALMetadata" }, { TIFFTAG_GDAL_NODATA, -1,-1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, (char*) "GDALNoDataValue" }, { TIFFTAG_RPCCOEFFICIENT, -1,-1, TIFF_DOUBLE, FIELD_CUSTOM, TRUE, TRUE, (char*) "RPCCoefficient" } }; if (_ParentExtender) (*_ParentExtender)(tif); TIFFMergeFieldInfo( tif, xtiffFieldInfo, sizeof(xtiffFieldInfo) / sizeof(xtiffFieldInfo[0]) ); } /* call it only once in the lifetime of the program before opening/creating a TIFF */ void InstallGDALTiffTags() { _ParentExtender = TIFFSetTagExtender(GTiffTagExtender); } /* end of patch to accomodate unofficial extended TIFFTAGS */ /***********************************************************************/ void print_mia_banner() { /* char banner[512] = MIA_BANNER; */ char banner[512] = { [0 ... 511] = ' ' }; printf("%s\n", banner); } /** * @synopsis tiffinfo fn field val * * @param fn a string for the name of a TIFF file (possibly including its path) * * @param field a string for the TIFF field name * * @param val holding the value of the specified field * * @desc the following field names are valid: TIFFTAG_IMAGEWIDTH, TIFFTAG_IMAGELENGTH, TIFFTAG_BITSPERSAMPLE, TIFFTAG_SAMPLESPERPIXEL, TIFFTAG_SAMPLEFORMAT (1 for unsigned integer data, 2 for two's complement signed integer data, and 3 for floating point data), GTModelTypeGeoKey (1 for projected, 2 for geographic, and 3 for geocentric), GeographicTypeGeoKey, ProjectedCSTypeGeoKey, and GTRasterTypeGeoKey (1 for RasterPixelIsArea). */ ERROR_TYPE tiffinfo(char *fn, char *field, float *val) { TIFF *tiffp; GTIF *gtif=NULL; uint32_t a_uint32; uint16_t a_uint16; geocode_t gkey_val; /* if ((tiffp = TIFFOpen(fn, "rc")) == NULL){ */ /* (void)sprintf(buf,"ERROR in tiffinfo(): invalid TIFF file name \"%s\" \n", fn); errputstr(buf); */ /* return ERROR; */ /* } */ /* Open TIFF descriptor to read GeoTIFF tags */ tiffp=XTIFFOpen(fn,"r"); if (!tiffp){ (void)sprintf(buf,"ERROR in tiffinfo(): invalid TIFF file name \"%s\" \n", fn); errputstr(buf); return ERROR; } gtif = GTIFNew(tiffp); if (strcmp(field,"TIFFTAG_IMAGEWIDTH")==0){ TIFFGetField(tiffp, TIFFTAG_IMAGEWIDTH, &a_uint32); *val=(float)a_uint32; } else if (strcmp(field,"TIFFTAG_IMAGELENGTH")==0){ TIFFGetField(tiffp, TIFFTAG_IMAGELENGTH, &a_uint32); *val=(float)a_uint32; } else if (strcmp(field,"TIFFTAG_BITSPERSAMPLE")==0){ TIFFGetField(tiffp, TIFFTAG_BITSPERSAMPLE, &a_uint16); *val=(float)a_uint16; } else if (strcmp(field,"TIFFTAG_SAMPLEFORMAT")==0){ if (TIFFGetField(tiffp, TIFFTAG_SAMPLEFORMAT, &a_uint16) == 1) *val=(float)a_uint16; else{ (void)sprintf(buf,"ERROR in tiffinfo(): no \"%s\" \n", field); errputstr(buf); return ERROR; } } else if (strcmp(field,"TIFFTAG_SAMPLESPERPIXEL")==0){ if (TIFFGetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, &a_uint16) == 1) *val=(float)a_uint16; else{ (void)sprintf(buf,"ERROR in tiffinfo(): no \"%s\" \n", field); errputstr(buf); return ERROR; } } else if (strcmp(field,"GeographicTypeGeoKey")==0){ if (GTIFKeyGet(gtif, GeographicTypeGeoKey, &gkey_val, 0, 1) == 1) *val=(float)gkey_val; else{ (void)sprintf(buf,"ERROR in tiffinfo(): no \"%s\" \n", field); errputstr(buf); return ERROR; } } else if (strcmp(field,"ProjectedCSTypeGeoKey")==0){ if (GTIFKeyGet(gtif, ProjectedCSTypeGeoKey, &gkey_val, 0, 1) == 1) *val=(float)gkey_val; else{ (void)sprintf(buf,"ERROR in tiffinfo(): no \"%s\" \n", field); errputstr(buf); return ERROR; } } else if (strcmp(field,"GTRasterTypeGeoKey")==0){ if (GTIFKeyGet(gtif, GTRasterTypeGeoKey, &gkey_val, 0, 1) == 1) *val=(float)gkey_val; else{ (void)sprintf(buf,"WARNING in tiffinfo(): no \"%s\", assuming default is RasterPixelIsArea (1)\n", field); errputstr(buf); *val=1; } } else if (strcmp(field,"GTModelTypeGeoKey")==0){ if (GTIFKeyGet(gtif, GTModelTypeGeoKey, &gkey_val, 0, 1) == 1) *val=(float)gkey_val; else{ (void)sprintf(buf,"ERROR in tiffinfo(): no \"%s\" \n", field); errputstr(buf); return ERROR; } } else{ (void)sprintf(buf,"ERROR in tiffinfo(): invalid TIFF TAG NAME \"%s\" \n", field); errputstr(buf); return ERROR; } if (gtif!=NULL) GTIFFree(gtif); TIFFClose(tiffp); return NO_ERROR; } /** * @synopsis tiffinfoJIP fn field val * * @param fn a string for the name of a TIFF file (possibly including its path) * * * @return an image holding the values of the fields values in the indicated order * * @desc the following sequence of values are inserted in the image: TIFFTAG_IMAGEWIDTH, TIFFTAG_IMAGELENGTH, TIFFTAG_BITSPERSAMPLE, TIFFTAG_SAMPLESPERPIXEL, TIFFTAG_SAMPLEFORMAT (1 for unsigned integer data, 2 for two's complement signed integer data, and 3 for floating point data), GTModelTypeGeoKey (1 for projected, 2 for geographic, and 3 for geocentric), GeographicTypeGeoKey, ProjectedCSTypeGeoKey, and GTRasterTypeGeoKey (1 for RasterPixelIsArea). */ IMAGE *tiffinfoJIP(char *fn) { TIFF *tiffp; GTIF *gtif=NULL; IMAGE *im=NULL; UINT32 *pim; uint32_t a_uint32; uint16_t a_uint16; geocode_t gkey_val; /* Open TIFF descriptor to read GeoTIFF tags */ tiffp=XTIFFOpen(fn,"r"); if (!tiffp){ (void)sprintf(buf,"ERROR in tiffinfoJIP(): invalid TIFF file name \"%s\" \n", fn); errputstr(buf); return NULL; } gtif = GTIFNew(tiffp); im=create_image(t_UINT32, 9, 1, 1); if (im==NULL){ if (gtif!=NULL) GTIFFree(gtif); TIFFClose(tiffp); return NULL; } pim=(UINT32 *)GetImPtr(im); TIFFGetField(tiffp, TIFFTAG_IMAGEWIDTH, &a_uint32); pim[0]=(UINT32)a_uint32; TIFFGetField(tiffp, TIFFTAG_IMAGELENGTH, &a_uint32); pim[1]=(UINT32)a_uint32; TIFFGetField(tiffp, TIFFTAG_BITSPERSAMPLE, &a_uint16); pim[2]=(UINT32)a_uint16; if (TIFFGetField(tiffp, TIFFTAG_SAMPLEFORMAT, &a_uint16) == 1) pim[3]=(UINT32)a_uint16; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"TIFFTAG_SAMPLEFORMAT\" \n" ); errputstr(buf); pim[3]=(UINT32)UINT32_MAX; } if (TIFFGetField(tiffp, TIFFTAG_SAMPLESPERPIXEL, &a_uint16) == 1) pim[4]=(UINT32)a_uint16; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"TIFFTAG_SAMPLESPERPIXEL\" (assuming 1)\n"); errputstr(buf); pim[4]=(UINT32)1; } if (GTIFKeyGet(gtif, GeographicTypeGeoKey, &gkey_val, 0, 1) == 1) pim[5]=(UINT32)gkey_val; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"GeographicTypeGeoKey\" \n"); errputstr(buf); pim[5]=(UINT32)UINT32_MAX; } if (GTIFKeyGet(gtif, ProjectedCSTypeGeoKey, &gkey_val, 0, 1) == 1) pim[6]=(UINT32)gkey_val; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"ProjectedCSTypeGeoKey\" \n"); errputstr(buf); pim[6]=(UINT32)UINT32_MAX; } if (GTIFKeyGet(gtif, GTRasterTypeGeoKey, &gkey_val, 0, 1) == 1) pim[7]=(UINT32)gkey_val; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"GTRasterTypeGeoKey\", assuming default is RasterPixelIsArea (1)\n"); errputstr(buf); pim[7]=(UINT32)UINT32_MAX; } if (GTIFKeyGet(gtif, GTModelTypeGeoKey, &gkey_val, 0, 1) == 1) pim[8]=(UINT32)gkey_val; else{ (void)sprintf(buf,"warning in tiffinfoJIP(): no \"GTModelTypeGeoKey\" \n"); errputstr(buf); pim[8]=(UINT32)UINT32_MAX; } if (gtif!=NULL) GTIFFree(gtif); TIFFClose(tiffp); return im; } IMAGE *GetGeoKey(char *fname, char *keyname) { IMAGE *im; INT32 *ptr; TIFF *tif=(TIFF*)0; /* TIFF-level descriptor */ GTIF *gtif=(GTIF*)0; /* GeoKey-level descriptor */ geocode_t modelTypeCode; // , rasterModelType; int count=1; /* Open TIFF descriptor to read GeoTIFF tags */ tif=TIFFOpen(fname,"r"); if (!tif) return NULL; /* Open GTIF Key parser; keys will be read at this time. */ gtif = GTIFNew(tif); if (!gtif) return NULL; if (strcmp(keyname,"GTModelTypeGeoKey")==0){ GTIFKeyGet(gtif, GTModelTypeGeoKey, &modelTypeCode, 0, 1); } else{ printf("GeoKey '%s' not handled\n", keyname); return NULL; } /* get rid of the key parser */ GTIFFree(gtif); /* close the TIFF file descriptor */ TIFFClose(tif); im=create_image(t_INT32, count, 1, 1); ptr=(INT32 *)GetImPtr(im); *ptr=(INT32)modelTypeCode; return im; } IMAGE *GetTIFFTagGeo(char *fn, char *tagname) { TIFF *tiffp=NULL; IMAGE *im=NULL; int i, erflag=0; uint16_t count=0; double *data=NULL; double *ptr=NULL; GTIF *gtif=(GTIF*)NULL; /* GeoKey-level descriptor */ /* DOC: */ /* TIFFTAG_GEOTIEPOINTS, &count, &values); */ /* TIFFGetField(tiff, TIFFTAG_GEOPIXELSCALE, &count, &values); */ /* TIFFGetField(tiff, TIFFTAG_GEOTRANSMATRIX, &count, &values); */ /* TIFFGetField returns 0 on failure (as opposed to the more */ /* common convention of 0 on success). */ /* count is the number of double precision values. For tiepoints, */ /* count should always be an even multiple of 6. For pixel scale, */ /* count should always be 3. For the transformation matrix, count */ /* should always be 16. */ /* For tiepoints, 'values' is ordered as (i, j, k, x, y, z) for */ /* each tiepoint. For pixel scale, values is ordered x, y, z. */ /* For the matrix, values provides a 4x4 matrix order as 4 left-to-right */ /* rows top-to-bottom. libtiff allocates and cleans up the memory */ /* holding this array. The caller is NOT responsible for freeing this */ /* array. */ if ((tiffp = TIFFOpen(fn, "rc")) == NULL){ (void)sprintf(buf,"ERROR in GetTIFFTagGeo(): invalid TIFF file name \"%s\" \n", fn); errputstr(buf); return NULL; } //not used: gtif = GTIFNew(tiffp); if (strcmp(tagname,"TIFFTAG_GEOTIEPOINTS")==0){ if (TIFFGetField(tiffp, TIFFTAG_GEOTIEPOINTS, &count, &data)==0){ (void)sprintf(buf,"ERROR in *GetTIFFTagGeo(%s, %s): no tie points found\n", fn, tagname); errputstr(buf); erflag=1; } #ifdef DEBUG else{ printf("data[3]=%20.40g\n", data[3]); printf("data[4]=%20.40g\n", data[4]); } #endif } else if (strcmp(tagname,"TIFFTAG_GEOPIXELSCALE")==0){ if (TIFFGetField(tiffp, TIFFTAG_GEOPIXELSCALE, &count, &data)==0){ (void)sprintf(buf,"ERROR in *GetTIFFTagGeo(%s, %s): no pixel scale found\n", fn, tagname); errputstr(buf); erflag=1; } } else if (strcmp(tagname,"TIFFTAG_GEOTRANSMATRIX")==0){ if (TIFFGetField(tiffp, TIFFTAG_GEOTRANSMATRIX, &count, &data)==0){ (void)sprintf(buf,"ERROR in *GetTIFFTagGeo(%s, %s): no transformation matrix found\n", fn, tagname); errputstr(buf); erflag=1; } } else{ (void)sprintf(buf,"ERROR in *GetTIFFTagGeo(%s, %s): unrecognised tag\n", fn, tagname); errputstr(buf); erflag=1; } if (erflag){ if (gtif!=NULL) GTIFFree(gtif); TIFFClose(tiffp); return NULL; } im=create_image(t_DOUBLE, count, 1, 1); if (im==NULL){ if (gtif!=NULL) GTIFFree(gtif); TIFFClose(tiffp); return NULL; } ptr=(double *)GetImPtr(im); for (i=0; i>16; test++; break; case 257: /* ImageLength tag */ ny = tag_info[i].ValOrPoint>>16; test++; break; case 258: /* BitPerSample tag */ bitpp = tag_info[i].ValOrPoint>>16; test++; break; case 273: /* StripOffset tag */ s_o_t = tag_info[i].ValOrPoint; test++; break; } } /* Reading facultatif tags */ nz = 1; /* 2D image by default */ for (i = 0; i < nbr_tags; i++){ switch (tag_info[i].type){ case 262: /* PhotometricInterpretation */ pmi = tag_info[i].ValOrPoint>>16; break; case 320: /* ColorMap */ cm = tag_info[i].ValOrPoint; break; case 1000: case 32768: nz = tag_info[i].ValOrPoint>>16; break; } } #endif /* big-endian */ free((char *)tag_info); if (test != 4){ (void)sprintf(buf, "read_tiff_file(): Tags missing !!! Unable to read file on disk.\n"); errputstr(buf); return(NULL); } if (bitpp == 1) data_type = t_TIFFONEBITPERPIXEL; else if (bitpp == 4) data_type = t_FOURBITPERPIXEL; else if (bitpp == BITPERCHAR) data_type = t_UCHAR; else if (bitpp == BITPERSHORT) data_type = t_USHORT; else if (bitpp == BITPERINT32) data_type = t_INT32; else if (bitpp == BITPERDOUBLE) data_type = t_DOUBLE; /* Allow for color images */ if (pmi == 2) data_type = t_RGB; /* check block to read */ if ( (x+szx > nx) || (y+szy > ny) || (nz != 1) ){ /* invalid parameters */ (void)sprintf(buf,"read_tiff_file(): invalid block parameters x=%d y=%d szx=%d szy=%d nx=%d ny=%d nz=%d!\n", x, y, szx, szy, nx, ny, nz); errputstr(buf); return NULL; } else if (szx==0 || szy==0){ /* default: read all image removed on 8 Apr 2003 || data_type != t_UCHAR */ x=0; y=0; inx=nx; nx=inx/scale; ny/=scale; } else{ /* block size */ inx=nx; nx=szx; ny=szy; } /* create output image */ im = create_image(data_type, nx, ny, nz); if (im == NULL){ (void)sprintf(buf,"read_tiff_file2(): not enough memory!\n"); errputstr(buf); return(NULL); } /* Read image data */ (void)fseek(fp, s_o_t, 0); /* position file pointer to pixel map */ /* read image data */ if (read_image_data2(fp, im, x, y, inx, scale) != NO_ERROR){ free_image(im); return(NULL); } /* read Color Map if any */ if (cm!=0){ plut = (unsigned short int *)malloc(3*(2<nx) || (szy>ny) ){ TIFFClose(tif); (void)sprintf(buf,"readTiffSubset(%s,...): subset not included in input image\n", fn); errputstr(buf); return NULL; } if (TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sf) != 1) sf=1; /* default: unsigned integer data */ if (bps == BITPERCHAR) data_type = t_UCHAR; else if ( (bps == BITPERSHORT) && (sf==1) ) data_type = t_USHORT; else if ( (bps == BITPERSHORT) && (sf==2) ) data_type = t_SHORT; else if ( (bps == BITPERINT32) && (sf==1) ) data_type = t_UINT32; else if ( (bps == BITPERINT32) && (sf==2) ) data_type = t_INT32; else if ( (bps == BITPERINT32) && (sf==3) ) data_type = t_FLOAT; else if ( (bps == BITPERDOUBLE) && (sf==3) ) data_type = t_DOUBLE; else{ TIFFClose(tif); (void)sprintf(buf,"readTiffSubset(%s,...): Unsupported pixel type \ (BitsPerSample=%d\tSampleFormat=%d)\n",fn,bps,sf); errputstr(buf); return NULL; } im=create_image(data_type, szx, szy, 1); if (im == NULL){ TIFFClose(tif); (void)sprintf(buf,"readTiffSubset(%s,...): not enough memory\n", fn); errputstr(buf); return(NULL); } bpp=GetImBitPerPixel(im)/8; /* byte(s) per pixel */ pim=(UCHAR *)GetImPtr(im); ptmp=(UCHAR *)malloc(nx*bpp); if (ptmp == NULL){ TIFFClose(tif); free_image(im); (void)sprintf(buf,"readTiffSubset(%s,...): not enough memory\n", fn); errputstr(buf); return(NULL); } for(stripCount=0; stripCount UINT32_MAX ){ (void)printf("writetiffospl() message: output file %s will be a bigtiff file\n", fn); *mp++ = '8'; *mp = '\0'; } tif = XTIFFOpen(fn, mode); /* X necessary for geotags */ if (tif==NULL){ (void)sprintf(buf,"writetiffospl(): unable to write %s on disk\n", fn); errputstr(buf); return ERROR; } gtif = GTIFNew(tif); if (!gtif){ TIFFClose(tif); (void)sprintf(buf,"writeGeoTiffOneStripPerLine(): error when calling GTIFNew()\n"); errputstr(buf); return ERROR; } if (PCSCode==4326){ /* ugly since it is NOT projected, but refers to GeographicTypeGeoKey */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 2); /* 2 for Geographic latitude-longitude System */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, PCSCode); /* 32767 for user-defined */ } else if (PCSCode==65535){ /* assumes wgs84 */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 2); /* 2 for Geographic latitude-longitude System */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ // GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "wgs84"); GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, 6378137.0); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, 298.257222101); GTIFKeySet(gtif, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 0.0); //GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9104); // 9104 for Angular_Arc_Second //GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree //GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); } else if ( (PCSCode!=3035) && (PCSCode!=65535) ) { GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 1); /* 1 for projected */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, PCSCode); } else{ GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, PCSCode); /* 3035 (ETRS-LAEA) not yet recognised by ArcGis: let insert also all parameters without codes */ GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 1, "JRC-EGCS"); /* name of the GeoTIFF scheme */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 1); /* 1 for projected */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ // GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); /* ETRS 1989 */ GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "ETRS89"); // GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 6258); /* Euro. Terr. Ref. Sys. 1989 */ // GTIFKeySet(gtif, GeogPrimeMeridianGeoKey, TYPE_DOUBLE, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogPrimeMeridianGeoKey, TYPE_DOUBLE, 1, 8901); /* Greenwich */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree // GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 7019); /* GRS 1980 */ GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, 6378137.0); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, 298.257222101); GTIFKeySet(gtif, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 0.0); // GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ // GTIFKeySet(gtif, PCSCitationGeoKey, TYPE_ASCII, 1, "ETRS-LAEA"); GTIFKeySet(gtif, PCSCitationGeoKey, TYPE_ASCII, 1, "ETRS89 / ETRS-LAEA"); /* 4326 for WGS_84 4258 for GCS_EUREF89 */ /* GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); */ GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1, 32767); GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 10); /* 10 for CT_LambertAzimEqualArea */ GTIFKeySet(gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); /* Linear_Metre=9001 */ GTIFKeySet(gtif, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, 4321000.0); GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, 3210000.0); GTIFKeySet(gtif, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, 10.0); GTIFKeySet(gtif, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, 52.0); } GTIFWriteKeys(gtif); GTIFFree(gtif); TIFFSetField(tif, TIFFTAG_GEOPIXELSCALE, 3, pixsize); TIFFSetField(tif, TIFFTAG_GEOTIEPOINTS, 6, tiepoint); TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, GetImBitPerPixel(im)); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, nz); if (nz > 1) TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE); else TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW); if ( GetImBitPerPixel(im) <= 16 ) TIFFSetField(tif, TIFFTAG_PREDICTOR, 2); /* PREDICTOR_HORIZONTAL = 2 */ if ( (GetImDataType(im)==t_RGB) || (GetImNz(im)==3) ) TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); else TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); switch (GetImDataType(im)){ /* set SampleFormat field value */ case t_UCHAR: case t_USHORT: case t_UINT32: case t_RGB: sf=1; /* unsigned integer data */ break; case t_SHORT: case t_INT32: sf=2; /* two's complement signed integer data */ break; case t_FLOAT: case t_DOUBLE: sf=3; /* IEEE floating point data */ break; default:/* undefined data format */ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): undefined data format\n", fn); errputstr(buf); return ERROR; } TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sf); TIFFSetField(tif, TIFFTAG_DATETIME, getCrtTimeString(timeString)); TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, fn); #if (defined(XLISP)) TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl-xlisp [mialisp]"); #elif (defined(PYTHON)) TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl-python"); #else TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl"); #endif localhost_str = (char *)malloc(1024); if (localhost_str != NULL){ if (gethostname(localhost_str, 1024)==0){ TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, localhost_str); } free(localhost_str); } TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, imdesc); TIFFSetField(tif, TIFFTAG_ARTIST, user_str); if (nodata_flag==1){ if (sf>2){ printf("warning, nodata flag ignored: only allowed for integer data type\n"); } else{ sprintf(nodata_str, "%d", nodata_val); TIFFSetField(tif, TIFFTAG_GDAL_NODATA, &nodata_str); } } if (metadata_flag==1){ TIFFSetField(tif, TIFFTAG_GDAL_METADATA, metadata_str); } lbuf=(void *)malloc(nx*bpp); if (lbuf==NULL){ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): not enough memory for line buffer\n", fn); errputstr(buf); return ERROR; } for(stripCount=0; stripCount UINT32_MAX ){ (void)printf("writetiffospl() message: output file %s will be a bigtiff file\n", fn); *mp++ = '8'; *mp = '\0'; } tif = XTIFFOpen(fn, mode); /* X necessary for geotags */ if (tif==NULL){ (void)sprintf(buf,"writetiffospl(): unable to write %s on disk\n", fn); errputstr(buf); return ERROR; } gtif = GTIFNew(tif); if (!gtif){ TIFFClose(tif); (void)sprintf(buf,"writeGeoTiffOneStripPerLine(): error when calling GTIFNew()\n"); errputstr(buf); return ERROR; } if (PCSCode==4326){ /* ugly since it is NOT projected, but refers to GeographicTypeGeoKey */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 2); /* 2 for Geographic latitude-longitude System */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, PCSCode); /* 32767 for user-defined */ } else if (PCSCode==65535){ /* assumes wgs84 */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 2); /* 2 for Geographic latitude-longitude System */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ // GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "wgs84"); GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, 6378137.0); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, 298.257222101); GTIFKeySet(gtif, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 0.0); //GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9104); // 9104 for Angular_Arc_Second //GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree //GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); } else if ( (PCSCode!=3035) && (PCSCode!=65535) ) { GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 1); /* 1 for projected */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, PCSCode); } else{ GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, PCSCode); /* 3035 (ETRS-LAEA) not yet recognised by ArcGis: let insert also all parameters without codes */ GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 1, "JRC-EGCS"); /* name of the GeoTIFF scheme */ GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, 1); /* 1 for projected */ GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterType); /* 1 for RasterPixelIsArea */ // GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); /* ETRS 1989 */ GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "ETRS89"); // GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT, 1, 6258); /* Euro. Terr. Ref. Sys. 1989 */ // GTIFKeySet(gtif, GeogPrimeMeridianGeoKey, TYPE_DOUBLE, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogPrimeMeridianGeoKey, TYPE_DOUBLE, 1, 8901); /* Greenwich */ GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT, 1, 9102); // 9102 for Angular_Arc_Degree // GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT, 1, 7019); /* GRS 1980 */ GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, 6378137.0); GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, 298.257222101); GTIFKeySet(gtif, GeogPrimeMeridianLongGeoKey, TYPE_DOUBLE, 1, 0.0); // GTIFKeySet(gtif, ProjectedCSTypeGeoKey, TYPE_SHORT, 1, 32767); /* 32767 for user-defined */ // GTIFKeySet(gtif, PCSCitationGeoKey, TYPE_ASCII, 1, "ETRS-LAEA"); GTIFKeySet(gtif, PCSCitationGeoKey, TYPE_ASCII, 1, "ETRS89 / ETRS-LAEA"); /* 4326 for WGS_84 4258 for GCS_EUREF89 */ /* GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, 4258); */ GTIFKeySet(gtif, ProjectionGeoKey, TYPE_SHORT, 1, 32767); GTIFKeySet(gtif, ProjCoordTransGeoKey, TYPE_SHORT, 1, 10); /* 10 for CT_LambertAzimEqualArea */ GTIFKeySet(gtif, ProjLinearUnitsGeoKey, TYPE_SHORT, 1, 9001); /* Linear_Metre=9001 */ GTIFKeySet(gtif, ProjFalseEastingGeoKey, TYPE_DOUBLE, 1, 4321000.0); GTIFKeySet(gtif, ProjFalseNorthingGeoKey, TYPE_DOUBLE, 1, 3210000.0); GTIFKeySet(gtif, ProjCenterLongGeoKey, TYPE_DOUBLE, 1, 10.0); GTIFKeySet(gtif, ProjCenterLatGeoKey, TYPE_DOUBLE, 1, 52.0); } GTIFWriteKeys(gtif); GTIFFree(gtif); TIFFSetField(tif, TIFFTAG_GEOPIXELSCALE, 3, pixsize); TIFFSetField(tif, TIFFTAG_GEOTIEPOINTS, 6, tiepoint); TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, nx); TIFFSetField(tif, TIFFTAG_IMAGELENGTH, ny); TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, GetImBitPerPixel(im)); TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, nz); if (nz > 1) TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_SEPARATE); else TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); TIFFSetField(tif, TIFFTAG_COMPRESSION, COMPRESSION_LZW); if ( GetImBitPerPixel(im) <= 16 ) TIFFSetField(tif, TIFFTAG_PREDICTOR, 2); /* PREDICTOR_HORIZONTAL = 2 */ if ( (GetImDataType(im)==t_RGB) || (GetImNz(im)==3) ) TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); else TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); switch (GetImDataType(im)){ /* set SampleFormat field value */ case t_UCHAR: case t_USHORT: case t_UINT32: case t_RGB: sf=1; /* unsigned integer data */ break; case t_SHORT: case t_INT32: sf=2; /* two's complement signed integer data */ break; case t_FLOAT: case t_DOUBLE: sf=3; /* IEEE floating point data */ break; default:/* undefined data format */ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): undefined data format\n", fn); errputstr(buf); return ERROR; } TIFFSetField(tif, TIFFTAG_SAMPLEFORMAT, sf); TIFFSetField(tif, TIFFTAG_DATETIME, getCrtTimeString(timeString)); TIFFSetField(tif, TIFFTAG_DOCUMENTNAME, fn); #if (defined(XLISP)) TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl-xlisp [mialisp]"); #elif (defined(PYTHON)) TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl-python"); #else TIFFSetField(tif, TIFFTAG_SOFTWARE, "jipl"); #endif TIFFSetField(tif, TIFFTAG_IMAGEDESCRIPTION, imdesc); localhost_str = (char *)malloc(1024); if (localhost_str != NULL){ if (gethostname(localhost_str, 1024)==0){ TIFFSetField(tif, TIFFTAG_HOSTCOMPUTER, localhost_str); } free(localhost_str); } TIFFSetField(tif, TIFFTAG_ARTIST, user_str); if (nodata_flag==1){ if (sf>2){ printf("warning, nodata flag ignored: only allowed for integer data type\n"); } else{ sprintf(nodata_str, "%d", nodata_val); TIFFSetField(tif, TIFFTAG_GDAL_NODATA, &nodata_str); } } if (metadata_flag==1){ TIFFSetField(tif, TIFFTAG_GDAL_METADATA, metadata_str); } lbuf=(void *)malloc(nx*bpp); if (lbuf==NULL){ TIFFClose(tif); (void)sprintf(buf,"writetiffospl(%s): not enough memory for line buffer\n", fn); errputstr(buf); return ERROR; } stripCount=0; for (z=0; z. ***********************************************************************/ /* Need to read arbitrary raster files. This need appears for the Core003 data holding tiled GeoTIFF files. See also GDAL API: http://www.gdal.org/gdal_tutorial.html First: 20121105 First working: 20121106 (needed to install version 1.9.2 to solve a bug for reading tiled images ...) 20160217: computation of min/max now only with -DDEBUG */ #include #include #include #include #include #include /* #include for CPLMalloc() but I use standard malloc */ #include "miallib.h" /** \addtogroup group_io * @{ */ /** * @synopsis Data type conversion from gdal to mial * * @param aGDALDataType integer for gdal data type * * @return integer with mial data type matching the input gdal data type * * @creationdate 20130911 */ int GDAL2MIALDataType(int aGDALDataType) { switch (aGDALDataType){ case GDT_Byte: return t_UCHAR; case GDT_UInt16: return t_USHORT; case GDT_Int16: return t_SHORT; case GDT_UInt32: return t_UINT32; case GDT_Int32: return t_INT32; case GDT_Float32: return t_FLOAT; /* case GDT_UInt64: */ /* return t_UINT64; */ /* case GDT_Int64: */ /* return t_INT64; */ case GDT_Unknown: return t_UNSUPPORTED; default: return t_UNSUPPORTED; } } /** * @synopsis read a single band of a raster image using drivers installed in gdal library * * @param fn a string for the name of an image file (possibly including its path) * @param band an integer for the band number, 0 for first band * @param nXOff: The pixel offset to the top left corner of the region of the band to be accessed. This would be zero to start from the left side (default value). * @param nYOff: The line offset to the top left corner of the region of the band to be accessed. This would be zero to start from the top (default value). * @param nXSize: The width of the region of the band to be accessed in pixels. * @param nYSize: The height of the region of the band to be accessed in lines. * @param nBufXSize: integer for number of columns of output image (default is nXSize). * @param nBufYSize: integer for number of lines of output image (default is nYSize) * @desc read a given band of a raster image using gdal with the specified options. Any invalid geometry parameter will result in the whole image domain to be read! */ IMAGE *GDALRead(char *imfn, int band, int nXOff, int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize) { /* ** Input Parameters: ** char *imfn: file name possibly including path ** int band: index of band to read (0 for first band). ** int nXOff: The pixel offset to the top left corner of the region of the band to be accessed. ** This would be zero to start from the left side. ** int nYOff: The line offset to the top left corner of the region of the band to be accessed. ** This would be zero to start from the top. ** int nXSize: The width of the region of the band to be accessed in pixels. ** int nYSize: The height of the region of the band to be accessed in lines. ** int nBufXSize: the width of the buffer image into which the desired region is to be read, or from which it is to be written. ** int nBufYSize: the height of the buffer image into which the desired region is to be read, or from which it is to be written. ** ** ** Return: an image on success, NULL otherwise ** ** Comment: any invalid geometry parameter will result in the whole image domain to be read! ** ** Authors: Pierre Soille */ GDALDatasetH hDataset; GDALDriverH hDriver; double adfGeoTransform[6]; GDALRasterBandH hBand; int nBlockXSize, nBlockYSize; #if DEBUG int bGotMin, bGotMax; double adfMinMax[2]; #endif void *imptr; IMAGE *im; GDALAllRegister(); /* opening the image file */ // hDataset = GDALOpen( imfn, GA_ReadOnly ); // GDALOpenEx introduced in 2.0 hDataset = GDALOpenEx( imfn, GDAL_OF_RASTER | \ GDAL_OF_READONLY | \ GDAL_OF_VERBOSE_ERROR, \ NULL, NULL, NULL ); if( hDataset == NULL ) return NULL; #if DEBUG printf("IMAGE FILE OPENED SUCCESSFULLY by GDALOpen\n"); #endif /* printing some information */ hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( "Size is %dx%dx%d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), GDALGetRasterCount( hDataset ) ); if( GDALGetProjectionRef( hDataset ) != NULL ) printf( "Projection is `%s'\n", GDALGetProjectionRef( hDataset ) ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){ printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } band+=1; if ((band <1) || (band > GDALGetRasterCount( hDataset ))){ printf("GDALRead(): invalid band number\n"); GDALClose(hDataset); return NULL; } printf("nXOff=%d nYOff=%d nXSize=%d nYSize=%d\n", nXOff, nYOff, nXSize, nYSize); /* if no patch, == should be replaced by < */ if ( (nXOff<0) || (nYOff<0) || (nXSize==0) || (nYSize==0) ){ nXOff=nYOff=0; nXSize= GDALGetRasterXSize( hDataset ); nYSize= GDALGetRasterYSize( hDataset ); } if ( (nBufXSize<=0) || (nBufYSize<=0) ){ nBufXSize=nXSize; nBufYSize=nYSize; } if ( ((nXOff+nXSize)>GDALGetRasterXSize( hDataset )) \ || ((nYOff+nYSize)>GDALGetRasterYSize( hDataset ))){ printf("GDALRead(): nXOff or nXSize (resp. Y.) parameters out of permissible range\n"); printf("nXOff=%d nYOff=%d nXSize=%d nYSize=%d\n", nXOff, nYOff, nXSize, nYSize); GDALClose(hDataset); return NULL; } /* Fetching a Raster Band */ hBand = GDALGetRasterBand( hDataset, band ); switch(GDAL2MIALDataType(GDALGetRasterDataType(hBand))){ case t_UCHAR: // bpp=1; break; case t_USHORT: case t_SHORT: // bpp=2; break; case t_UINT32: case t_INT32: case t_FLOAT: // bpp=4; break; case t_DOUBLE: // bpp=8; break; default: printf("gdalread(): invalid type(=%d), detaching shared memory ...\n", GDAL2MIALDataType(GDALGetRasterDataType(hBand))); GDALClose(hDataset); return NULL; } #if DEBUG printf("gdalread(): nXSize=%d, nYSize=%d, nXOff=%d nYOff=%d band=%d type=%d\n nBufXSize=%d, nBufYSize=%d\n", nXSize, nYSize, nXOff, nYOff, band,GDAL2MIALDataType(GDALGetRasterDataType(hBand)), nBufXSize, nBufYSize); #endif /* note: even if a subset is read, is is inserted in the full raster (limitation of GDALRasterIO) */ im = create_image(GDAL2MIALDataType(GDALGetRasterDataType(hBand)), \ nBufXSize, \ nBufYSize, \ 1); if (im == NULL){ (void)sprintf(buf,"GDALRead(): not enough memory!\n"); errputstr(buf); GDALClose(hDataset); return NULL; } GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize ); printf( "Block=%dx%d Type=%s, ColorInterp=%s\n", nBlockXSize, nBlockYSize, GDALGetDataTypeName(GDALGetRasterDataType(hBand)), GDALGetColorInterpretationName(GDALGetRasterColorInterpretation(hBand)) ); #ifdef DEBUG adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin ); adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax ); if( ! (bGotMin && bGotMax) ) GDALComputeRasterMinMax( hBand, TRUE, adfMinMax ); printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] ); #endif if( GDALGetOverviewCount(hBand) > 0 ) printf( "Band has %d overviews.\n", GDALGetOverviewCount(hBand)); if( GDALGetRasterColorTable( hBand ) != NULL ) printf( "Band has a color table with %d entries.\n", GDALGetColorEntryCount( GDALGetRasterColorTable( hBand ) ) ); /* Reading Raster Data */ imptr = GetImPtr(im); if (GDALRasterIO( hBand, GF_Read, nXOff, nYOff, nXSize, nYSize, \ imptr, nBufXSize, nBufYSize, \ GDALGetRasterDataType(hBand), 0, 0) != CPLE_None){ (void)sprintf(buf,"GDALRead(): call to GDALRasterIO() returns error!\n"); errputstr(buf); GDALClose(hDataset); free_image(im); return NULL; } GDALClose(hDataset); return im; } /** * The values are in the following order: x-coordinate of upper left corner of upper left pixel, W-E pixel resolution, rotation (0 if image is north up), x-coordinate of upper left corner of upper left pixel, rotation (0 if image is north up), N-S pixel resolution, number of rows of raster, number of columns of raster, number of bands of raster, and EPSG code of projection (-1 if it could not be retrieved). The function also prints in stdout the type of driver used for reading fn and the name of the projection. * * @param imfn string for image file name * * @return an image of type t_DOUBLE holding 10 values regarding the geolocation and size of the image, NIL otherwise */ IMAGE *GDALInfoJIP(char *imfn) { GDALDatasetH hDataset; GDALDriverH hDriver; double adfGeoTransform[6]; printf("entering gdalinfo\n"); IMAGE *im=NULL; double *ptr=NULL; OGRSpatialReferenceH hSRS=NULL; GDALAllRegister(); hDataset = GDALOpen( imfn, GA_ReadOnly ); if( hDataset == NULL ) return NULL; printf("after GDALOpen\n"); hDriver = GDALGetDatasetDriver( hDataset ); printf( "Driver: %s/%s\n", GDALGetDriverShortName( hDriver ), GDALGetDriverLongName( hDriver ) ); printf( "Size is %dx%dx%d\n", GDALGetRasterXSize( hDataset ), GDALGetRasterYSize( hDataset ), GDALGetRasterCount( hDataset ) ); if( GDALGetProjectionRef( hDataset ) != NULL ) printf( "Projection is `%s'\n", GDALGetProjectionRef( hDataset ) ); if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None ){ printf( "Origin = (%.6f,%.6f)\n", adfGeoTransform[0], adfGeoTransform[3] ); printf( "Pixel Size = (%.6f,%.6f)\n", adfGeoTransform[1], adfGeoTransform[5] ); } im=create_image(t_DOUBLE, 10, 1, 1); if (im==NULL){ GDALClose(hDataset); return NULL; } ptr=(double *)GetImPtr(im); ptr[0]=adfGeoTransform[0]; /* top left x */ ptr[1]=adfGeoTransform[1]; /* w-e pixel resolution */ ptr[2]=adfGeoTransform[2]; /* rotation, 0 if image is "north up" */ ptr[3]=adfGeoTransform[3]; /* top left y */ ptr[4]=adfGeoTransform[4]; /* rotation, 0 if image is "north up" */ ptr[5]=fabs(adfGeoTransform[5]); /* n-s pixel resolution */ ptr[6]=GDALGetRasterXSize( hDataset ); /* image width in number of pixels */ ptr[7]=GDALGetRasterYSize( hDataset ); /* image length in number of pixels */ ptr[8]=GDALGetRasterCount( hDataset ); /* number of image bands */ ptr[9]=-1; hSRS= OSRNewSpatialReference(GDALGetProjectionRef( hDataset )); if (hSRS!=NULL){ if(OSRGetAttrValue(hSRS, "AUTHORITY", 1)!=NULL){ printf( "EPSG=%s\n", OSRGetAttrValue(hSRS, "AUTHORITY", 1)); ptr[9]=(double)atoi(OSRGetAttrValue(hSRS, "AUTHORITY", 1)); } else printf("*gdalinfo() warning: getting GEOGCS EPSG code failed\n"); } else printf("*gdalinfo() warning: getting GEOGCS EPSG code failed\n"); GDALClose(hDataset); return im; } /* test for reading block by blocks assuming NO padding ! */ /* */ /* nBlockY=(mia_size_t)(nYSize/nBlockYSize); */ /* nBlockX=(mia_size_t)(nXSize/nBlockXSize); */ /* bim = create_image(GDAL2MIALDataType(GDALGetRasterDataType(hBand)), \ */ /* nBlockXSize, \ */ /* nBlockYSize, \ */ /* 1); */ /* if (bim == NULL){ */ /* (void)sprintf(buf,"GDALRead(): not enough memory!\n"); errputstr(buf); */ /* GDALClose(hDataset); */ /* free_image(im); */ /* return NULL; */ /* } */ /* bimptr = (UCHAR *)GetImPtr(bim); */ /* for( iYBlock = 0; iYBlock < nBlockY; iYBlock++ ) */ /* { */ /* for( iXBlock = 0; iXBlock < nBlockX; iXBlock++ ) */ /* { */ /* printf("reading block i=%d j=%d\n", (int)iXBlock, (int)iYBlock); */ /* //GDALReadBlock( hBand, iXBlock*nBlockXSize, iYBlock*nBlockYSize, imptr); */ /* if (GDALReadBlock( hBand, iXBlock, iYBlock, bimptr)== CE_Failure) */ /* printf("failure when reaing block!!!\n"); */ /* iminfo(bim); */ /* imputop(im, bim, iXBlock*nBlockXSize, iYBlock*nBlockYSize, 0, 5); */ /* generic_blank(bim, 0); */ /* } */ /* } */ /* test for reading scan line by scan line ! */ /* pafScanline = (UCHAR *)GetImPtr(im); */ /* for (i=0; i. ***********************************************************************/ #include #include #if !defined(__APPLE__) #include #endif #include #include "miallib.h" extern float roundf(float x); /** @defgroup group_stat Image statistics and pixel sorting * Functions computing image statistics, some other target information as well as pixel sorting * @{ */ #include "uc_def.h" ERROR_TYPE uc_getfirstmaxpos(IMAGE *im, unsigned long int *pos) { unsigned long int i, npix; PIX_TYPE *p1, maxi=PIX_MIN; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); *pos=0; for (i=0; imaxi){ maxi = *p1; *pos=i; } } return(NO_ERROR); } #include "uc_undef.h" #include "f_def.h" ERROR_TYPE f_getfirstmaxpos(IMAGE *im, unsigned long int *pos) { unsigned long int i, npix; PIX_TYPE *p1, maxi=PIX_MIN; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); *pos=0; for (i=0; imaxi){ maxi = *p1; *pos=i; } } return(NO_ERROR); } #include "f_undef.h" #include "d_def.h" ERROR_TYPE d_getfirstmaxpos(IMAGE *im, unsigned long int *pos) { unsigned long int i, npix; PIX_TYPE *p1, maxi=PIX_MIN; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); *pos=0; for (i=0; imaxi){ maxi = *p1; *pos=i; } } return(NO_ERROR); } #include "d_undef.h" ERROR_TYPE getfirstmaxpos(IMAGE *im, unsigned long int *pos) { switch (GetImDataType(im)){ case t_UCHAR: uc_getfirstmaxpos(im, pos); break; case t_FLOAT: f_getfirstmaxpos(im, pos); break; case t_DOUBLE: d_getfirstmaxpos(im, pos); break; default: (void)sprintf(buf,"getfirstmaxpos(im): invalid pixel type\n"); errputstr(buf); return(ERROR); } return NO_ERROR; } /*************************************************************************/ /* Compute min and max values of an image */ #include "g_def.h" ERROR_TYPE generic_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].generic_val = mini; pg[1].generic_val = maxi; #if (t_PIX_TYPE==t_UCHAR) pg[0].uc_val = mini; pg[1].uc_val = maxi; #endif return(NO_ERROR); } #include "g_undef.h" #include "uc_def.h" ERROR_TYPE uc_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].uc_val = mini; pg[1].uc_val = maxi; #if (t_PIX_TYPE==t_GENERIC) pg[0].generic_val = mini; pg[1].generic_val = maxi; #endif return(NO_ERROR); } #include "uc_undef.h" #include "s_def.h" ERROR_TYPE s_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].s_val = mini; pg[1].s_val = maxi; return(NO_ERROR); } #include "s_undef.h" #include "u32_def.h" ERROR_TYPE u32_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].u32_val = mini; pg[1].u32_val = maxi; return(NO_ERROR); } #include "u32_undef.h" #include "i64_def.h" ERROR_TYPE i64_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].i64_val = mini; pg[1].i64_val = maxi; return(NO_ERROR); } #include "i64_undef.h" #include "u64_def.h" ERROR_TYPE u64_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].u64_val = mini; pg[1].u64_val = maxi; return(NO_ERROR); } #include "u64_undef.h" #include "f_def.h" ERROR_TYPE f_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].f_val = mini; pg[1].f_val = maxi; return(NO_ERROR); } #include "f_undef.h" #include "d_def.h" ERROR_TYPE d_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].d_val = mini; pg[1].d_val = maxi; return(NO_ERROR); } #include "d_undef.h" #include "us_def.h" ERROR_TYPE us_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].us_val = mini; pg[1].us_val = maxi; return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_min_max(IMAGE *im, G_TYPE *pg) { mia_size_t i, npix; PIX_TYPE *p1, mini, maxi; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); mini = *p1; maxi = *p1; for (i=0; i maxi) maxi = *p1; } pg[0].i32_val = mini; pg[1].i32_val = maxi; return(NO_ERROR); } #include "i32_undef.h" G_TYPE *min_max(IMAGE *im) { G_TYPE *pg; ERROR_TYPE rval; /* allocate memory for range */ pg = (G_TYPE *)calloc((size_t)2,sizeof(G_TYPE)); if (pg == NULL){ (void)sprintf(buf,"min_max(im): not enough memory\n"); errputstr(buf); return(pg); } switch (GetImDataType(im)){ case t_UCHAR: rval = uc_min_max(im, pg); break; case t_USHORT: rval = us_min_max(im, pg); break; case t_SHORT: rval = s_min_max(im, pg); break; case t_UINT32: rval = u32_min_max(im, pg); break; case t_INT32: rval = i32_min_max(im, pg); break; case t_INT64: rval = i64_min_max(im, pg); break; case t_UINT64: rval = u64_min_max(im, pg); break; case t_FLOAT: rval = f_min_max(im, pg); break; case t_DOUBLE: rval = d_min_max(im, pg); break; default: (void)sprintf(buf,"min_max(im): invalid pixel type\n"); errputstr(buf); return(NULL); } if (rval == ERROR) free((char *)pg); return(pg); } /*************************************************************************/ /* */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_histo1d(IMAGE *im) { IMAGE *imout; PIX_TYPE *pcrt, *pend, maxi; HST1D_TYPE *phst; G_TYPE *pg; long int npix; #if SIGNED (void)sprintf(buf,"generic_histo1d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"generic_histo1d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im); /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxi = pg[1].generic_val; free((char *)pg); /* create histogram */ imout = (IMAGE *)create_image(t_HST1D, (int)maxi+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"generic_histo1d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im) + npix; for (pcrt = (PIX_TYPE *)GetImPtr(im); pcrt < pend; pcrt++) phst[*pcrt] += 1; return(imout); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "u32_def.h" IMAGE *u32_histo1d(IMAGE *im) { IMAGE *imout; PIX_TYPE *pcrt, *pend, maxi; HST1D_TYPE *phst; G_TYPE *pg; long int npix; #if SIGNED (void)sprintf(buf,"ul_histo1d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"ul_histo1d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im); /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxi = pg[1].u32_val; free((char *)pg); /* create histogram */ imout = (IMAGE *)create_image(t_HST1D, (int)maxi+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"ul_histo1d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im) + npix; for (pcrt = (PIX_TYPE *)GetImPtr(im); pcrt < pend; pcrt++) phst[*pcrt] += 1; return(imout); } #include "u32_undef.h" #include "us_def.h" IMAGE *us_histo1d(IMAGE *im) { IMAGE *imout; PIX_TYPE *pcrt, *pend, maxi; HST1D_TYPE *phst; G_TYPE *pg; long int npix; #if SIGNED (void)sprintf(buf,"us_histo1d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"us_histo1d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im); /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxi = pg[1].us_val; free((char *)pg); /* create histogram */ imout = (IMAGE *)create_image(t_HST1D, (int)maxi+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"us_histo1d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im) + npix; for (pcrt = (PIX_TYPE *)GetImPtr(im); pcrt < pend; pcrt++) phst[*pcrt] += 1; return(imout); } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_histo1d(IMAGE *im) { IMAGE *imout; PIX_TYPE *pcrt, *pend, maxi, mini; HST1D_TYPE *phst; G_TYPE *pg; long int npix; #if FLOATING (void)sprintf(buf,"l_histo1d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im); /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxi = pg[1].i32_val; mini = pg[0].i32_val; free((char *)pg); if (mini < 0){ (void)sprintf(buf,"l_histo1d(): negative values(mini=%d) not handled\n", (int)mini); errputstr(buf); return(NULL); } /* create histogram */ imout = (IMAGE *)create_image(t_HST1D, (int)maxi+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"l_histo1d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im) + npix; for (pcrt = (PIX_TYPE *)GetImPtr(im); pcrt < pend; pcrt++) phst[*pcrt] += 1; return(imout); } #include "i32_undef.h" IMAGE *histo1d(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_histo1d(im)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_histo1d(im)); break; #endif case t_USHORT: return(us_histo1d(im)); break; case t_INT32: return(i32_histo1d(im)); break; case t_UINT32: return(u32_histo1d(im)); break; default: (void)sprintf(buf,"histo1d(im): invalid pixel type\n"); errputstr(buf); } return(NULL); } /*************************************************************************/ /* */ #ifndef NO_generic_IMAGE #define HST2D_TYPE_LOCAL UINT32 #define t_HST2D_LOCAL t_UINT32 #include "g_def.h" IMAGE *generic_histo2d(IMAGE *im1, IMAGE *im2) { IMAGE *imout; PIX_TYPE *pcrt, *pend, *p2; PIX_TYPE maxi1, maxi2; HST2D_TYPE_LOCAL *phst; G_TYPE *pg; long int npix, nx; #if SIGNED (void)sprintf(buf,"generic_histo2d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"generic_histo2d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im1); /* get min & max values */ pg = min_max(im1); if (pg == NULL) return(NULL); maxi1 = pg[1].generic_val; pg = min_max(im2); if (pg == NULL) return(NULL); maxi2 = pg[1].generic_val; free((char *)pg); /* create histogram */ nx = maxi1+1; imout = (IMAGE *)create_image(t_HST2D_LOCAL, (int)nx, (int)maxi2+1, (int)1); if (imout == NULL){ (void)sprintf(buf,"generic_histo2d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST2D_TYPE_LOCAL *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im1) + npix; p2 = (PIX_TYPE *)GetImPtr(im2); for (pcrt = (PIX_TYPE *)GetImPtr(im1); pcrt < pend; pcrt++, p2++) phst[*pcrt + *p2 * nx] += 1; return(imout); } #include "g_undef.h" #undef HST2D_TYPE_LOCAL #undef t_HST2D_LOCAL #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" #define HST2D_TYPE_LOCAL UINT32 #define t_HST2D_LOCAL t_UINT32 IMAGE *us_histo2d(IMAGE *im1, IMAGE *im2) { IMAGE *imout; PIX_TYPE *pcrt, *pend, *p2; PIX_TYPE maxi1, maxi2; HST2D_TYPE_LOCAL *phst; G_TYPE *pg; long int npix, nx; #if SIGNED (void)sprintf(buf,"us_histo2d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"us_histo2d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im1); /* get min & max values */ pg = min_max(im1); if (pg == NULL) return(NULL); maxi1 = pg[1].us_val; pg = min_max(im2); if (pg == NULL) return(NULL); maxi2 = pg[1].us_val; free((char *)pg); /* create histogram */ nx = maxi1+1; imout = (IMAGE *)create_image(t_HST2D_LOCAL, (int)nx, (int)maxi2+1, (int)1); if (imout == NULL){ (void)sprintf(buf,"us_histo2d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST2D_TYPE_LOCAL *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im1) + npix; p2 = (PIX_TYPE *)GetImPtr(im2); for (pcrt = (PIX_TYPE *)GetImPtr(im1); pcrt < pend; pcrt++, p2++) phst[*pcrt + *p2 * nx] += 1; return(imout); } #undef HST2D_TYPE_LOCAL #undef t_HST2D_LOCAL #include "us_undef.h" IMAGE *histo2d(IMAGE *im1, IMAGE *im2) { /* check for possible errors */ if (szcompat(im1, im2) != NO_ERROR){ (void)sprintf(buf,"ERROR in *histo2d(im1, im2): \ images of different size or type\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_histo2d(im1, im2)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_histo2d(im1, im2)); break; #endif case t_USHORT: return(us_histo2d(im1, im2)); break; #ifndef NO_u32_IMAGE case t_UINT32: return(u32_histo2d(im1, im2)); break; #endif default: (void)sprintf(buf,"histo2d(im1, im2): invalid pixel type\n"); errputstr(buf); } return(NULL); } /*************************************************************************/ /* */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_histo3d(IMAGE *im1, IMAGE *im2, IMAGE *im3) { IMAGE *imout; PIX_TYPE *pcrt, *pend, *p2, *p3; PIX_TYPE maxi1, maxi2, maxi3; HST3D_TYPE *phst; G_TYPE *pg; long int npix, nx, nxy; #if SIGNED (void)sprintf(buf,"generic_histo3d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"generic_histo3d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im1); /* get min & max values */ pg = min_max(im1); if (pg == NULL) return(NULL); maxi1 = pg[1].generic_val; pg = min_max(im2); if (pg == NULL) return(NULL); maxi2 = pg[1].generic_val; free((char *)pg); pg = min_max(im3); if (pg == NULL) return(NULL); maxi3 = pg[1].generic_val; free((char *)pg); /* create histogram */ nx = maxi1+1; nxy = (maxi1+1) * (maxi2+1); imout = (IMAGE *)create_image(t_HST3D, (int)nx, (int)maxi2+1, (int)maxi3+1); if (imout == NULL){ (void)sprintf(buf,"generic_histo3d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST3D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im1) + npix; p2 = (PIX_TYPE *)GetImPtr(im2); p3 = (PIX_TYPE *)GetImPtr(im3); for (pcrt = (PIX_TYPE *)GetImPtr(im1); pcrt < pend; pcrt++, p2++, p3++) phst[*pcrt + *p2 * nx + *p3 * nxy] += 1; return(imout); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" IMAGE *us_histo3d(IMAGE *im1, IMAGE *im2, IMAGE *im3) { IMAGE *imout; PIX_TYPE *pcrt, *pend, *p2, *p3; PIX_TYPE maxi1, maxi2, maxi3; HST3D_TYPE *phst; G_TYPE *pg; long int npix, nx, nxy; #if SIGNED (void)sprintf(buf,"us_histo3d(): signed data type not handled\n"); errputstr(buf); return(NULL); #endif #if FLOATING (void)sprintf(buf,"us_histo3d(): float data type not handled\n"); errputstr(buf); return(NULL); #endif npix = GetImNPix(im1); /* get min & max values */ pg = min_max(im1); if (pg == NULL) return(NULL); maxi1 = pg[1].us_val; pg = min_max(im2); if (pg == NULL) return(NULL); maxi2 = pg[1].us_val; free((char *)pg); pg = min_max(im3); if (pg == NULL) return(NULL); maxi3 = pg[1].us_val; free((char *)pg); /* create histogram */ nx = maxi1+1; nxy = (maxi1+1) * (maxi2+1); imout = (IMAGE *)create_image(t_HST3D, (int)nx, (int)maxi2+1, (int)maxi3+1); if (imout == NULL){ (void)sprintf(buf,"us_histo3d(): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST3D_TYPE *)GetImPtr(imout); pend = (PIX_TYPE *)GetImPtr(im1) + npix; p2 = (PIX_TYPE *)GetImPtr(im2); p3 = (PIX_TYPE *)GetImPtr(im3); for (pcrt = (PIX_TYPE *)GetImPtr(im1); pcrt < pend; pcrt++, p2++, p3++) phst[*pcrt + *p2 * nx + *p3 * nxy] += 1; return(imout); } #include "us_undef.h" IMAGE *histo3d(IMAGE *im1, IMAGE *im2, IMAGE *im3) { /* check for possible errors */ if ((szcompat(im1, im2) != NO_ERROR) || (szcompat(im1, im3) != NO_ERROR)){ (void)sprintf(buf,"ERROR in *histo3d(im1, im2, im3): \ images of different size or type\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_histo3d(im1, im2, im3)); break; #endif case t_USHORT: return(us_histo3d(im1, im2, im3)); break; default: (void)sprintf(buf,"histo3d(im1, im2, im3): invalid pixel type\n"); errputstr(buf); } return(NULL); } /*************************************************************************/ /* */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_rsum(IMAGE *im) { IMAGE *imout; PIX_TYPE *pim; HST1D_TYPE *phst; long int npix, i; npix = GetImNPix(im); /* create array for summing up */ imout = (IMAGE *)create_image(t_HST1D, (int)npix+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"generic_rsum(im): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); phst[0] = pim[0]; for (i=1; i0; i--) /* phst[i] = #{ p | f(p) < i } */ phst[i] = phst[i-1]; phst[0] = 0; return(imout); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "u32_def.h" IMAGE *u32_rsum(IMAGE *im) { IMAGE *imout; PIX_TYPE *pim; HST1D_TYPE *phst; long int npix, i; npix = GetImNPix(im); /* create array for summing up */ imout = (IMAGE *)create_image(t_HST1D, (int)npix+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"ul_rsum(im): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); phst[0] = pim[0]; for (i=1; i0; i--) /* phst[i] = #{ p | f(p) < i } */ phst[i] = phst[i-1]; phst[0] = 0; return(imout); } #include "u32_undef.h" #include "i32_def.h" IMAGE *i32_rsum(IMAGE *im) { IMAGE *imout; PIX_TYPE *pim; HST1D_TYPE *phst; long int npix, i; npix = GetImNPix(im); /* create array for summing up */ imout = (IMAGE *)create_image(t_HST1D, (int)npix+1, (int)1, (int)1); if (imout == NULL){ (void)sprintf(buf,"l_rsum(im): not enough memory!\n"); errputstr(buf); return(imout); } phst = (HST1D_TYPE *)GetImPtr(imout); pim = (PIX_TYPE *)GetImPtr(im); phst[0] = pim[0]; for (i=1; i0; i--) phst[i] = phst[i-1]; phst[0] = 0; return(imout); } #include "i32_undef.h" IMAGE *rsum(IMAGE *im) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_rsum(im)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_rsum(im)); break; #endif #ifndef NO_us_IMAGE case t_USHORT: return(us_rsum(im)); break; #endif #ifndef NO_s_IMAGE case t_SHORT: return(s_rsum(im)); break; #endif case t_UINT32: return(u32_rsum(im)); break; case t_INT32: return(i32_rsum(im)); break; default: (void)sprintf(buf,"rsum(): invalid pixel type\n"); errputstr(buf); } return(NULL); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_histcompress(IMAGE *im) { IMAGE *imhst; HST1D_TYPE *phst; PIX_TYPE *pim, val=0; unsigned long i, nval, npix; imhst = histo1d(im); if (imhst==NULL) return(ERROR); phst = (HST1D_TYPE *)GetImPtr(imhst); nval = GetImNPix(imhst); pim = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); for(i=0;imaxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); else if (lut[p[i]]>PIX_MAX){ (void)sprintf(buf,"warning: lookup(): LUT value greater than PIX_MAX value (output set to PIX_MAX)\n"); p[i]=PIX_MAX; } else if (lut[p[i]]maxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); else if (lut[p[i]]>PIX_MAX){ (void)sprintf(buf,"warning: lookup(): LUT value greater than PIX_MAX value (output set to PIX_MAX)\n"); p[i]=PIX_MAX; } else if (lut[p[i]]maxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); else if (lut[p[i]]>PIX_MAX){ (void)sprintf(buf,"warning: lookup(): LUT value greater than PIX_MAX value (output set to PIX_MAX)\n"); p[i]=PIX_MAX; } else if (lut[p[i]]maxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); /* the following tests are not necessary since image type is equal to lut type */ /* else if (val>PIX_MAX){ */ /* (void)sprintf(buf,"warning: lookup(): LUT value greater than PIX_MAX value (output set to PIX_MAX)\n"); */ /* p[i]=PIX_MAX; */ /* } */ /* else if (valmaxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); else p[i]=lut[p[i]]; } return NO_ERROR; } #include "uc_undef.h" #include "u32_def.h" ERROR_TYPE u32_lookuptypematch(IMAGE *im, IMAGE *imlut) { /* generic code for unsigned integer types only */ long int i; long int npix=GetImNPix(im); int maxlutidx=GetImNPix(imlut)-1; PIX_TYPE *p=(PIX_TYPE *)GetImPtr(im); PIX_TYPE *lut=(PIX_TYPE *)GetImPtr(imlut); #pragma omp parallel for for(i=0;imaxlutidx) (void)sprintf(buf,"warning: lookup(): LUT not matching image values\n"); else p[i]=lut[p[i]]; } return NO_ERROR; } #include "u32_undef.h" ERROR_TYPE lookuptypematch(IMAGE *im, IMAGE *imlut) { if (GetImDataType(imlut)!=GetImDataType(im)){ (void)sprintf(buf,"lookup(): imlut must be with the same type as im\n"); errputstr(buf); return ERROR; } switch (GetImDataType(im)){ case t_UCHAR: return(uc_lookuptypematch(im, imlut)); break; case t_UINT32: return(u32_lookuptypematch(im, imlut)); break; default: (void)sprintf(buf,"lookuptypematch(): invalid pixel type\n"); errputstr(buf); } return(ERROR); } #include "uc_def.h" #define LUTRGB_TYPE UCHAR IMAGE *uc_lookuprgb(IMAGE *imr, IMAGE *img, IMAGE *imb, IMAGE *imlut) { /* Developed for colour histogram matching (for GMES CORE003 data set) First 20130430 */ /* generic code for unsigned integer types only */ IMAGE *imout; long int i,idx; long int npix=GetImNPix(imr); int maxlutidx=GetImNPix(imlut)-1; int nxlut=GetImNx(imlut); int nylut=GetImNy(imlut); PIX_TYPE *p; PIX_TYPE *pr=(PIX_TYPE *)GetImPtr(imr); PIX_TYPE *pg=(PIX_TYPE *)GetImPtr(img); PIX_TYPE *pb=(PIX_TYPE *)GetImPtr(imb); LUTRGB_TYPE *lut=(LUTRGB_TYPE *)GetImPtr(imlut); imout=create_image(t_PIX_TYPE, GetImNx(imr), GetImNy(imr), GetImNz(imr)); if (imout==NULL) return NULL; p=(PIX_TYPE *)GetImPtr(imout); #pragma omp parallel for private(i,idx) for(i=0;imaxlutidx) (void)sprintf(buf,"warning: lookuprgb(): LUT not matching image values\n"); else if (lut[idx]>PIX_MAX){ (void)sprintf(buf,"warning: lookuprgb(): LUT value greater than PIX_MAX value (output set to PIX_MAX)\n"); p[i]=PIX_MAX; } else if (lut[idx]*aux_max_a) *aux_max_a++=*aux_im--; else *aux_im--=*aux_max_a++; free((char*)max_a); break; case 1: aux_im=pim; for(j=0;jmax) max=*aux_im++; else *aux_im++=max; break; case 2: if((max_a=(PIX_TYPE *)malloc(nx*sizeof(PIX_TYPE)))==(PIX_TYPE *)NULL) return(ERROR); for(i=0,aux_max_a=max_a;i*aux_max_a) *aux_max_a++=*aux_im++; else *aux_im++=*aux_max_a++; free((char*)max_a); break; case 3: aux_im=pim+nx*ny-1; for(j=0;jmax) max=*aux_im--; else *aux_im--=max; break; default: return(ERROR); } return(NO_ERROR); } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_dirmax(IMAGE *im, int dir) { /* ** im: an 1d array for a 2d image ** nx: number of image columns ** ny: number of image lines ** dir: direction 0=down-top, 1=left-right ** 2=top-down, 3=right-left */ int i,j,nx,ny; PIX_TYPE max=0,*max_a; PIX_TYPE *pim, *aux_max_a,*aux_im; pim = (PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); switch(dir){ case 0: if((max_a=(PIX_TYPE *)malloc(nx*sizeof(PIX_TYPE)))==(PIX_TYPE *)NULL) return(ERROR); for(i=0,aux_max_a=max_a;i*aux_max_a) *aux_max_a++=*aux_im--; else *aux_im--=*aux_max_a++; free((char*)max_a); break; case 1: aux_im=pim; for(j=0;jmax) max=*aux_im++; else *aux_im++=max; break; case 2: if((max_a=(PIX_TYPE *)malloc(nx*sizeof(PIX_TYPE)))==(PIX_TYPE *)NULL) return(ERROR); for(i=0,aux_max_a=max_a;i*aux_max_a) *aux_max_a++=*aux_im++; else *aux_im++=*aux_max_a++; free((char*)max_a); break; case 3: aux_im=pim+nx*ny-1; for(j=0;jmax) max=*aux_im--; else *aux_im--=max; break; case 31: for(j=0;jmax) max=*aux_im; aux_im=pim+(j*nx); for(i=0;imax) max=*aux_im; aux_im=pim+j; for(i=0;i*aux_max_a) *aux_max_a++=*aux_im--; else *aux_im--=*aux_max_a++; free((char*)max_a); break; case 1: aux_im=pim; for(j=0;jmax) max=*aux_im++; else *aux_im++=max; break; case 2: if((max_a=(PIX_TYPE *)malloc(nx*sizeof(PIX_TYPE)))==(PIX_TYPE *)NULL) return(ERROR); for(i=0,aux_max_a=max_a;i*aux_max_a) *aux_max_a++=*aux_im++; else *aux_im++=*aux_max_a++; free((char*)max_a); break; case 3: aux_im=pim+nx*ny-1; for(j=0;jmax) max=*aux_im--; else *aux_im--=max; break; default: return(ERROR); } return(NO_ERROR); } #include "f_undef.h" ERROR_TYPE dirmax(IMAGE *im, int dir) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_dirmax(im, dir)); break; case t_USHORT: return(us_dirmax(im, dir)); break; case t_FLOAT: return(f_dirmax(im, dir)); break; default: (void)sprintf(buf, "Error in dirmax(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(ERROR); } #include "f_def.h" #define PIX_TYPE_OUT float IMAGE *f_dirsum(IMAGE *im, int dir) { /* ** im: an image ** dir: direction 0=vertical, 1=horizontal ** */ int i,j,nx,ny; PIX_TYPE *pim; IMAGE *imout; PIX_TYPE_OUT *pout; pim = (PIX_TYPE *)GetImPtr(im); nx = GetImNx(im); ny = GetImNy(im); switch(dir){ case 0: imout=create_image(t_FLOAT, nx, 1, 1); pout=(PIX_TYPE_OUT *)GetImPtr(imout); for(j=0;j. ***********************************************************************/ #include #include #include #include #include "miallib.h" /** \addtogroup group_stat * @{ */ int cmp_dbl (const void *a, const void *b) { const double x = *(const double *) a; const double y = *(const double *) b; if (x > y) return 1; if (x == y) return 0; else return -1; } int cmp_flt (const void *a, const void *b) { const float x = *(const float *) a; const float y = *(const float *) b; if (x > y) return 1; if (x == y) return 0; else return -1; } void indexx(size_t n, double arrin[], size_t indx[]) { gsl_heapsort_index (indx, arrin, n, sizeof (double), (gsl_comparison_fn_t) & cmp_dbl); } void f_indexx(size_t n, float arrin[], size_t indx[]) { gsl_heapsort_index (indx, arrin, n, sizeof (float), (gsl_comparison_fn_t) & cmp_flt); } /** @param i0 an image pointer @return a 1-D image (INT32 type) with the first pixel giving the offset to the smallest value of im, the second pixel the second smallest value, etc. The sorting is based on the heap sort of the GNU scientific library. */ IMAGE *sortindex(IMAGE *i0) { IMAGE *itmp, *imidx; int flag=0; if (GetImDataType(i0) != t_FLOAT){ itmp=to_float(i0); flag=1; if (itmp==NULL) return NULL; } else itmp=i0; imidx=(IMAGE *)create_image(t_UINT64, GetImNPix(i0), 1 , 1); if (imidx==NULL){ (void)sprintf(buf,"sortindex(): insufficient memory\n"); errputstr(buf); if (flag) free_image(itmp); return NULL; } f_indexx(GetImNPix(i0), ((MIALFLOAT *)GetImPtr(itmp)), ((size_t *)GetImPtr(imidx))); if (flag) free_image(itmp); return imidx; } /*@}*/ jeolib-miallib-1.1.6/core/c/label.c000066400000000000000000001007771467232417700170200ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* provides a distinct label to each connected component of a binary image it is ASSUMED that the input image has a zero valued frame accordingly to shft the first label is 2 */ /* im: pointer to I/O image */ /* nx: number of columns */ /* ny: number of lines */ /* nz: number of planes */ /* shft: array of shifts to access the neighbors */ /* n: numbers of shifts */ #include #include #include #include "miallib.h" #include "fifo.h" /** @defgroup group_label Connected component labelling * Functions labelling image connected components based on pre-defined connectivity relations. * The labelling of flat zones (labelplat function) is described in \cite soille2004sv * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { /* ** authors: P. Soille ** im1: Input and output image (destructive function) ** im2: UCHAR image defining neighbourhood (1 for a neighbour of origin) ** ox: x coordinate of origin ** oy: y coordinate of origin ** oz: z coordinate of origin ** comment: */ long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) /* no point in SE */ return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (generic_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected \ components, the remaining components have been labeled \ starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break; modified on 2003-06-20 crystal clear view on Weissmies */ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "u32_def.h" ERROR_TYPE u32_label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (u32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected components, the remaining components have been labeled starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break;*/ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "u32_undef.h" #include "i32_def.h" ERROR_TYPE i32_label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (i32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected components, the remaining components have been labeled starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break;*/ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "i32_undef.h" #include "us_def.h" ERROR_TYPE us_label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (us_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected components, the remaining components have been labeled starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break;*/ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "us_undef.h" ERROR_TYPE label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { /* im1: input image im2: for defining neighbourhgood */ switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_label(im1,im2,ox,oy,oz)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_label(im1,im2,ox,oy,oz)); break; #endif case t_USHORT: return(us_label(im1,im2,ox,oy,oz)); break; case t_INT32: return(i32_label(im1,im2,ox,oy,oz)); break; case t_UINT32: return(u32_label(im1,im2,ox,oy,oz)); break; default: (void)sprintf(buf,"label(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "us_def.h" ERROR_TYPE us_labelpixngb(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; /* first label with value 1 */ FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (i32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected components, the remaining components have been labeled starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break;*/ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = ++lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_labelpixngb(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (i32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p == 1){ if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): warning: there are more than %d connected components, the remaining components have been labeled starting again with label value 2!.\n", PIX_MAX); errputstr(buf); /* should add a flag to either stop the labelling with break or reset lbl */ /*break;*/ lbl=1; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == 1){ *p2 = ++lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "i32_undef.h" ERROR_TYPE labelpixngb(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { /* im1: input image im2: for defining neighbourhgood */ switch (GetImDataType(im1)){ case t_USHORT: return(us_labelpixngb(im1,im2,ox,oy,oz)); break; case t_INT32: return(i32_labelpixngb(im1,im2,ox,oy,oz)); break; default: (void)sprintf(buf,"label(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_labelplat(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (generic_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); for (; p < plast; p++){ if (*p > PIX_MSB){ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"labelplat(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_labelplat(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (us_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); for (; p < plast; p++){ if (*p > PIX_MSB){ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"labelplat(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_labelplat(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; FIFO4 *q; long int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (i32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); for (; p < plast; p++){ if (*p > PIX_MSB){ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"labelplat(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "i32_undef.h" /* labelplat function is described in \cite soille2004sv */ ERROR_TYPE labelplat(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz) { switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_labelplat(im1,im2,ox,oy,oz)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_labelplat(im1,im2,ox,oy,oz)); break; #endif case t_USHORT: return(us_labelplat(im1,im2,ox,oy,oz)); break; case t_INT32: case t_UINT32: return(i32_labelplat(im1,im2,ox,oy,oz)); break; default: (void)sprintf(buf,"labelplat(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_seededlabelplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (generic_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_seededlabelplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (us_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "us_undef.h" #include "u32_def.h" ERROR_TYPE u32_seededlabelplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE lbl = 1, val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (u32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; if (lbl==PIX_MAX){ (void)sprintf(buf,"label(): there are more than %d connected components, the remaining components have not been labeled.\n", PIX_MAX); errputstr(buf); break; } *p = ++lbl; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = lbl; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "u32_undef.h" ERROR_TYPE seededlabelplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_seededlabelplat(im1,im2,im3,ox,oy,oz)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_seededlabelplat(im1,im2,im3,ox,oy,oz)); break; #endif case t_USHORT: return(us_seededlabelplat(im1,im2,im3,ox,oy,oz)); break; case t_UINT32: return(u32_seededlabelplat(im1,im2,im3,ox,oy,oz)); break; default: (void)sprintf(buf,"seededlabelplat(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_seededplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { /* each flat region marked by a seed is set to 1 we assume that PIX_MSB and PIX_MSB-1 are not used in im1 */ long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (generic_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; *p = PIX_MSB-1; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = PIX_MSB-1; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; else if (*p > 0) *p =1; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" ERROR_TYPE us_seededplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { /* each flat region marked by a seed is set to 1 we assume that PIX_MSB and PIX_MSB-1 are not used in im1 */ long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (us_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; *p = PIX_MSB-1; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = PIX_MSB-1; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; else if (*p > 0) *p =1; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "us_undef.h" #include "u32_def.h" ERROR_TYPE u32_seededplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { /* each flat region marked by a seed is set to 1 we assume that PIX_MSB and PIX_MSB-1 are not used in im1 */ long int k, *shft, n; PIX_TYPE *p, *plast, *p1, *p2; PIX_TYPE val; UCHAR *p3; /* image of seeds for flat regions */ FIFO4 *q; int nx, ny, nz; int box[BOXELEM]; n = objectpix(im2); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(im2); box[1] = GetImNy(im2); box[2] = GetImNz(im2); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(im2), box, GetImNx(im1), GetImNy(im1), shft); if (i32_framebox(im1,box,0)==ERROR){ free((char*)shft); return ERROR; } nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p) /* shouldn't it be >= ??? for all (see below) */ *p |= PIX_MSB; } q = create_fifo4((nx*ny*nz)/100L); if (q == NULL){ free((char*)shft); return ERROR; } /* Here we go */ p = (PIX_TYPE *)GetImPtr(im1); p3 = (UCHAR *)GetImPtr(im3); for (; p < plast; p++, p3++){ if (*p > PIX_MSB && *p3){ /* shouldn't it be >= ??? */ val = *p; *p = PIX_MSB-1; fifo4_add(q, (long int)p); while ((p1 = (PIX_TYPE *)fifo4_remove(q))){ for (k=0; k < n; k++){ p2 = p1 + shft[k]; if (*p2 == val){ *p2 = PIX_MSB-1; fifo4_add(q, (long int)p2); } } } } } p = (PIX_TYPE *)GetImPtr(im1); plast = p + nx * ny * nz; for (; p < plast; p++){ if (*p>=PIX_MSB) /* shouldn't it be >= ??? for all (see below) */ *p = 0; else if (*p > 0) *p =1; } free((char*)shft); free_fifo4(q); return NO_ERROR; } #include "u32_undef.h" ERROR_TYPE seededplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_seededplat(im1,im2,im3,ox,oy,oz)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_seededplat(im1,im2,im3,ox,oy,oz)); break; #endif case t_USHORT: return(us_seededplat(im1,im2,im3,ox,oy,oz)); break; case t_UINT32: return(u32_seededplat(im1,im2,im3,ox,oy,oz)); break; default: (void)sprintf(buf,"seededplat(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #include "uc_def.h" ERROR_TYPE uc_labelpix(IMAGE *im) { unsigned long int i; PIX_TYPE *p=(PIX_TYPE *)GetImPtr(im), lbl=1; for(i=GetImNx(im)*GetImNy(im)*GetImNz(im); i>0; i--,p++) if (*p) *p=lbl++; return NO_ERROR; } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_labelpix(IMAGE *im) { unsigned long int i; PIX_TYPE *p=(PIX_TYPE *)GetImPtr(im), lbl=1; for(i=GetImNx(im)*GetImNy(im)*GetImNz(im); i>0; i--,p++) if (*p) *p=lbl++; return NO_ERROR; } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_labelpix(IMAGE *im) { unsigned long int i; PIX_TYPE *p=(PIX_TYPE *)GetImPtr(im), lbl=1; for(i=GetImNx(im)*GetImNy(im)*GetImNz(im); i>0; i--,p++) if (*p) *p=lbl++; return NO_ERROR; } #include "i32_undef.h" ERROR_TYPE labelpix(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_labelpix(im)); break; case t_USHORT: return(us_labelpix(im)); break; case t_INT32: case t_UINT32: return(i32_labelpix(im)); break; default: (void)sprintf(buf,"labelpix(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /**@}*/ jeolib-miallib-1.1.6/core/c/labelccdissim.c000066400000000000000000000325371467232417700205350ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2010-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Dissimilarity based alpha-omega connected components \cite soille2011ismm * [Version suitable for grey level images] * @author Pierre Soille */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF IMAGE *uc_labelccdissim(IMAGE *im, IMAGE *imh, IMAGE *imv, int rg, int rl) { /* First 2010-10-18: for transition regions: the ultimate solution? First brina this morning */ PIX_TYPE *p, *prmax, *plut, *ph, *pv; IMAGE *imlbl, *imrmax, *imlut; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio, mincc, maxcc, reset=0; long int k, *shft; int n=4, nx=GetImNx(im), ny, nz; int doffset[4]={-nx,-1,0,0}; PIX_TYPE *pdir[4]; FIFO4 *q; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; ny = GetImNy(im); nz = GetImNz(im); npix=GetImNPix(im); imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); return NULL; } imrmax= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imrmax == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); free_image(imlbl); return NULL; } imlut= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imlut == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); free_image(imlbl); free_image(imrmax); return NULL; } plut = (PIX_TYPE *)GetImPtr(imlut); generic_blank(imrmax, PIX_MAX); prmax = (PIX_TYPE *)GetImPtr(imrmax); pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); free_image(imrmax); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } if (n!=4){ // only 4-connectivity for now free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); free_fifo4(q); return NULL; } shft[0]=-nx; shft[1]=-1; shft[2]=1; shft[3]=nx; /* Take SE into account */ BOX_2D; if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free_image(imrmax); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ p = (PIX_TYPE *)GetImPtr(im); ph = (PIX_TYPE *)GetImPtr(imh); pv = (PIX_TYPE *)GetImPtr(imv); pdir[0]=pv; pdir[1]=ph; pdir[2]=ph; pdir[3]=pv; plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pdir[k]+i+doffset[k])) // abs(mincc-p[ofsk])) rlcrt= *(pdir[k]+i+doffset[k])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pdir[k]+i+doffset[k]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pdir[k]+ofs+doffset[k])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pdir[k]+ofs+doffset[k])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pdir[k]+ofs+doffset[k]); //(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } plut[lbl-511]=rlcrt; lbl++; } } free_image(imrmax); free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pdir[k]+i+doffset[k])) // abs(mincc-p[ofsk])) rlcrt= *(pdir[k]+i+doffset[k])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pdir[k]+i+doffset[k]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pdir[k]+ofs+doffset[k])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pdir[k]+ofs+doffset[k])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pdir[k]+ofs+doffset[k]); //(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } plut[lbl-511]=rlcrt; lbl++; } } free_image(imrmax); free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ /* the use of the lut image is commented (it relates to information regarding the external isolation 20110921 */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LAST_NLBL 0x000001FF /* 511 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF IMAGE *uc_labelcc(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rg, int rl) { /* First 2006-05-18: positive energy after IVC05 result */ PIX_TYPE *p, *prmax; //, *plut; IMAGE *imlbl, *imrmax; //, *imlut; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio, mincc, maxcc, reset=0; long int k, *shft; FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } imrmax= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imrmax == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); free_image(imlbl); return NULL; } /* imlut= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); */ /* if (imlut == NULL){ */ /* (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); */ /* free_image(imlbl); */ /* free_image(imrmax); */ /* return NULL; */ /* } */ /* plut = (PIX_TYPE *)GetImPtr(imlut); */ generic_blank(imrmax, PIX_MAX); prmax = (PIX_TYPE *)GetImPtr(imrmax); pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); free_image(imrmax); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR) return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free_image(imrmax); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ p = (PIX_TYPE *)GetImPtr(im); plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k=abs(mincc-p[ofsk])) rlcrt=abs(mincc-p[ofsk])-1; continue; } rk=abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } // DEBUG 2007-01-22 if (lbl==635) // DEBUG 2007-01-22 printf("rlcrt=%d\n", (int)rlcrt); /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ //plut[lbl-LAST_NLBL]=rcrt; // printf("plut[%d]=%d\n", (int)lbl, (int)rcrt); while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k=abs(p[ofs]-p[ofsk])){ rlcrt=abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=abs(p[ofs]-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset //BUG 2007 01 21 else{ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } //BUG 2007 01 21 } // plut[lbl-LAST_NLBL]=rlcrt; lbl++; } } //write_tiff(imrmax, "/tmp/simon.tif"); //write_tiff(imlut, "/tmp/lut.tif"); free_image(imrmax); // free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k=abs(mincc-p[ofsk])) rlcrt=abs(mincc-p[ofsk])-1; continue; } rk=abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } // DEBUG 2007-01-22 if (lbl==635) // DEBUG 2007-01-22 printf("rlcrt=%d\n", (int)rlcrt); /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ //plut[lbl-LAST_NLBL]=rcrt; // printf("plut[%d]=%d\n", (int)lbl, (int)rcrt); while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k=abs(p[ofs]-p[ofsk])){ rlcrt=abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=abs(p[ofs]-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset //BUG 2007 01 21 else{ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } //BUG 2007 01 21 } // plut[lbl-LAST_NLBL]=rlcrt; lbl++; } } //write_tiff(imrmax, "/tmp/simon.tif"); //write_tiff(imlut, "/tmp/lut.tif"); free_image(imrmax); // free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** * @file labelccmi.c * @author Pierre Soille * @date * * @details see also \cite soille2008pami */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define MI_TYPE UCHAR #define t_MI_TYPE t_UCHAR #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF IMAGE *uc_labelccmi(IMAGE *im, IMAGE *immi, IMAGE *imse, int ox, int oy, int oz, int rg, int rl) { /* First 2006-05-18: positive energy after IVC05 result */ PIX_TYPE *p, *prmax, *plut; MI_TYPE *pmi; IMAGE *imlbl, *imrmax, *imlut; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio, mincc, maxcc, reset=0; long int k, *shft; int nxmi=GetImNx(immi); FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } imrmax= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imrmax == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); free_image(imlbl); return NULL; } imlut= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imlut == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); free_image(imlbl); free_image(imrmax); return NULL; } pmi = (MI_TYPE *)GetImPtr(immi); plut = (PIX_TYPE *)GetImPtr(imlut); generic_blank(imrmax, PIX_MAX); prmax = (PIX_TYPE *)GetImPtr(imrmax); pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); free_image(imrmax); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free_image(imrmax); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ p = (PIX_TYPE *)GetImPtr(im); plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pmi+p[i]+nxmi*p[ofsk])) // abs(mincc-p[ofsk])) rlcrt= *(pmi+p[i]+nxmi*p[ofsk])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pmi+p[i]+nxmi*p[ofsk]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pmi+p[ofs]+nxmi*p[ofsk])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pmi+p[ofs]+nxmi*p[ofsk])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pmi+p[ofs]+nxmi*p[ofsk]); //(p[ofs]-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset //BUG 2007 01 21 else{ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } //BUG 2007 01 21 } plut[lbl-511]=rlcrt; lbl++; } } //write_tiff(imrmax, "/tmp/simon.tif"); write_tiff(imlut, "/tmp/lut.tif"); free_image(imrmax); free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pmi+p[i]+nxmi*p[ofsk])) // abs(mincc-p[ofsk])) rlcrt= *(pmi+p[i]+nxmi*p[ofsk])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pmi+p[i]+nxmi*p[ofsk]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pmi+p[ofs]+nxmi*p[ofsk])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pmi+p[ofs]+nxmi*p[ofsk])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pmi+p[ofs]+nxmi*p[ofsk]); //(p[ofs]-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset //BUG 2007 01 21 else{ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } //BUG 2007 01 21 } plut[lbl-511]=rlcrt; lbl++; } } //write_tiff(imrmax, "/tmp/simon.tif"); write_tiff(imlut, "/tmp/lut.tif"); free_image(imrmax); free_image(imlut); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** * @file labelccms.c * @author Pierre Soille * @date * * @details see also \cite soille2008pami */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF #define NCMAX 255 /* maximum number of channels */ IMAGE *uc_labelccms(IMAGE **imap, int nc, IMAGE *imse, int ox, int oy, int oz, int r1, int r2) { /* First 2006-06-06: positive energy after IVC05 result */ /* first attempt for multichannel version */ PIX_TYPE *p[NCMAX]; IMAGE *im, *imlbl; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, rtmp, prio, mincc[NCMAX], maxcc[NCMAX]; long int k, *shft; int c, flag_reset; FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; im=imap[0]; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR) return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ for (c=0;c=rtmp) rlcrt=rtmp-1; continue; } rk=abs(mincc[0]-p[0][ofsk]); for (c=1;crlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; //if (rcrt>rlcrt){ // fifo4_add(q, (long int)ofs); // goto myreset; //} if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); for (c=0; cmaxcc[c]) maxcc[c]=p[c][ofs]; } flag_reset=0; for (c=0; crlcrt)){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; } break; } // end reset for (k=0; k=rtmp){ rlcrt=rtmp-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[0][ofs]-p[0][ofsk]); for (c=1;crlcrt) continue; if(rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=rtmp) rlcrt=rtmp-1; continue; } rk=abs(mincc[0]-p[0][ofsk]); for (c=1;crlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; //if (rcrt>rlcrt){ // fifo4_add(q, (long int)ofs); // goto myreset; //} if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); for (c=0; cmaxcc[c]) maxcc[c]=p[c][ofs]; } flag_reset=0; for (c=0; crlcrt)){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; } break; } // end reset for (k=0; k=rtmp){ rlcrt=rtmp-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[0][ofs]-p[0][ofsk]); for (c=1;crlcrt) continue; if(rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** @file * Dissimilarity based alpha-omega connected components \cite soille2011ismm * [Version suitable for multi-band images] * @author Pierre Soille */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF #define NCMAX 255 /* maximum number of channels */ IMAGE *uc_labelccmsdissim(IMAGE **imap, int nc, IMAGE *imh, IMAGE *imv, int rg, int rl) { /* First 2010-10-18: for transition regions: the ultimate solution? First brina this morning */ PIX_TYPE *p[NCMAX], *prmax, *ph, *pv; IMAGE *im , *imlbl, *imrmax; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio, mincc[NCMAX], maxcc[NCMAX], reset=0; long int k, *shft; int n=4, nx=GetImNx(imap[0]), ny, nz; int doffset[4]={-nx,-1,0,0}; PIX_TYPE *pdir[4]; int c; int rgcrt; im=imap[0]; FIFO4 *q; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); return NULL; } imrmax= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imrmax == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); free_image(imlbl); return NULL; } generic_blank(imrmax, PIX_MAX); prmax = (PIX_TYPE *)GetImPtr(imrmax); pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); free_image(imrmax); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } if (n!=4){ // only 4-connectivity for now free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); free_fifo4(q); return NULL; } shft[0]=-nx; shft[1]=-1; shft[2]=1; shft[3]=nx; /* Take SE into account */ BOX_2D; if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free_image(imrmax); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ for (c=0;c=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pdir[k]+i+doffset[k])) // abs(mincc-p[ofsk])) rlcrt= *(pdir[k]+i+doffset[k])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pdir[k]+i+doffset[k]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } for (c=0; cmaxcc[c]) maxcc[c]=p[c][ofs]; } rgcrt=0; for(c=0; crlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pdir[k]+ofs+doffset[k])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pdir[k]+ofs+doffset[k])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pdir[k]+ofs+doffset[k]); //(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } lbl++; } } free_image(imrmax); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k= *(pdir[k]+i+doffset[k])) // abs(mincc-p[ofsk])) rlcrt= *(pdir[k]+i+doffset[k])-1; //abs(mincc-p[ofsk])-1; continue; } rk= *(pdir[k]+i+doffset[k]); //abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP rlcrt=rcrt-1; reset=1; break; //leave while loop } for (c=0; cmaxcc[c]) maxcc[c]=p[c][ofs]; } rgcrt=0; for(c=0; crlcrt) ){ /* reset */ rlcrt=rcrt-1; reset=1; break; //leave while loop } for (k=0; k= *(pdir[k]+ofs+doffset[k])){// abs(p[ofs]-p[ofsk])){ rlcrt= *(pdir[k]+ofs+doffset[k])-1; //abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=*(pdir[k]+ofs+doffset[k]); //(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; } if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } lbl++; } } free_image(imrmax); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** @file labelccvar.c * Connected component labelling using variance predicate \cite soille2007iciap * @author Pierre Soille */ #include #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF IMAGE *uc_labelccvar(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rg, int rl, double varmax) { /* First 2006-05-18: positive energy after IVC05 result */ PIX_TYPE *p, *prmax; IMAGE *imlbl, *imrmax; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio, mincc, maxcc, reset=0; long int k, *shft; FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; /* extension with var for iciap'07 2007-2-23 */ unsigned int hst[PIX_MAX+1]; /* histogram */ unsigned int sum, count; double mean, var; for(k=PIX_MAX;k>=0;k--){ hst[k]=0; } nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } imrmax= (IMAGE *)create_image(t_PIX_TYPE, nx, ny, nz); if (imrmax == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); free_image(imlbl); return NULL; } generic_blank(imrmax, PIX_MAX); prmax = (PIX_TYPE *)GetImPtr(imrmax); pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); free_image(imrmax); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR) return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_image(imrmax); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free_image(imrmax); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ p = (PIX_TYPE *)GetImPtr(im); plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=0;i=prmax[i]) // SPEED-UP rlcrt=prmax[i]-1; /* init queue */ for (k=0; k=abs(mincc-p[ofsk])) rlcrt=abs(mincc-p[ofsk])-1; continue; } rk=abs(mincc-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } // DEBUG 2007-01-22 if (lbl==635) // DEBUG 2007-01-22 printf("rlcrt=%d\n", (int)rlcrt); /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (prio>rcrt){ /* nth 'layer' done */ /* test whether variance is exceeded */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ if(plbl[ofsq]!=lbl){ hst[p[ofsq]]+=1; plbl[ofsq]=lbl; } } sum=0; count=0; for(k=PIX_MAX;k>=0;k--){ sum+=(k*hst[k]); count+=hst[k]; } mean=(double)sum/(double)count; var=0.0; for(k=PIX_MAX;k>=0;k--) var+=(hst[k]*(k-mean)*(k-mean)); var/=count; if (var>varmax){ reset=1; //GLOUP? rcrt+=1; //for(k=PIX_MAX;k>=0;k--) // printf("hst[%d]= %d\n", k, hst[k]); //printf("sum %d count %d\n", sum, count); //printf("variance exceeded %f\n", (float)var); break; //leave while loop } /* variance not exceeded */ while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP } rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (prmax[ofs]<=rcrt){ // SPEED-UP reset=1; break; //leave while loop } if (p[ofs]maxcc) maxcc=p[ofs]; if ( (rgrlcrt) ){ /* reset */ reset=1; break; //leave while loop } for (k=0; k=abs(p[ofs]-p[ofsk])){ rlcrt=abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt){ reset=1; break; } } } continue; } rk=abs(p[ofs]-p[ofsk]); //if (rlcrt>=prmax[ofsk]) // SPEED-UP //rlcrt=prmax[ofsk]-1; if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } if (reset) break; }// end while if (reset){ for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ // prmax[ofsq]=plbl[ofsq];// SPEED-UP plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ //if (plbl[ofsq]&LBL_BIT){ // printf("SHOULD NEVER HAPPEN!\n"); // continue; //} prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } reset=0; } // end reset /* test whether variance is exceeded */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ if(plbl[ofsq]!=lbl){ hst[p[ofsq]]+=1; plbl[ofsq]=lbl; } } sum=0; count=0; for(k=PIX_MAX;k>=0;k--){ sum+=(k*hst[k]); count+=hst[k]; } mean=(double)sum/(double)count; var=0.0; for(k=PIX_MAX;k>=0;k--) var+=(hst[k]*(k-mean)*(k-mean)); var/=count; if (var>varmax){ reset=1; //GLOUP? rcrt+=1; //printf("sum %d count %d\n", sum, count); //printf("variance exceeded %f\n", (float)var); } while ( (ofsq=fifo4_remove(q)) != 0){ if (!reset) plbl[ofsq]=lbl; //prmax[ofsq]=rcrt; // SPEED-UP else{ prmax[ofsq]=rcrt;// SPEED-UP plbl[ofsq]=R_BIT+1; //=rcrt; // =R_BIT+1; // rcrt; } } reset=0; lbl++; for(k=PIX_MAX;k>=0;k--){ hst[k]=0; } reset=0; // memset((void *)hst, (int)0, (size_t)(PIX_MAX+1)*sizeof(int)); } } write_tiff(imrmax, "/tmp/simon.tif"); free_image(imrmax); free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** * @file labelci.c * @author Pierre Soille * @date * * @details see also \cite soille2008pami */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 /* 512 */ #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF IMAGE *uc_labelci(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rl) { /* First 2006-07-31: after much reading and thinking */ PIX_TYPE *p, valcrt; IMAGE *imlbl; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, prio; long int k, *shft; FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR) return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ p = (PIX_TYPE *)GetImPtr(im); plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=0;i=abs(p[i]-p[ofsk])) rlcrt=abs(p[i]-p[ofsk])-1; continue; } rk=abs(p[i]-p[ofsk]); if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } // printf("after init, lbl=%d, rlcrt=%d, rcrt=%d\n", (int)lbl, rlcrt, rcrt); fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ printf("!!!!!!!!!!!!!! stack not empty!!!\n"); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ /* if (i>=33 && i<=40){ */ /* printf("lbl=%d, i=%d\n", lbl, i); */ /* printf("lbl=%d, rlcrt=%d, rcrt=%d\n", (int)lbl, rlcrt, rcrt); */ /* i32_dumpxyz(imlbl,0,0,0,20,20); */ /* } */ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (rcrt>rlcrt){ fifo4_add(q, (long int)ofs); goto myreset; } if (prio>rcrt){ /* nth 'layer' done */ /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ valcrt=p[ofsq]; for (k=0; krl){ /* ci<1 */ fifo4_add(q, (long int)ofs); goto myreset; } } } } /* ci=1 set current r-CC to lbl and proceed */ while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (rcrt>rlcrt){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; // rcrt; } break; } // end reset for (k=0; k=abs(p[ofs]-p[ofsk])){ rlcrt=abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ valcrt=p[ofsq]; for (k=0; krl){ /* ci<1 */ goto myreset2; } } } } while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } myreset2: while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=R_BIT+1; } lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=abs(p[i]-p[ofsk])) rlcrt=abs(p[i]-p[ofsk])-1; continue; } rk=abs(p[i]-p[ofsk]); if (rk>rlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } // printf("after init, lbl=%d, rlcrt=%d, rcrt=%d\n", (int)lbl, rlcrt, rcrt); fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ printf("!!!!!!!!!!!!!! stack not empty!!!\n"); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ /* if (i>=33 && i<=40){ */ /* printf("lbl=%d, i=%d\n", lbl, i); */ /* printf("lbl=%d, rlcrt=%d, rcrt=%d\n", (int)lbl, rlcrt, rcrt); */ /* i32_dumpxyz(imlbl,0,0,0,20,20); */ /* } */ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (rcrt>rlcrt){ fifo4_add(q, (long int)ofs); goto myreset; } if (prio>rcrt){ /* nth 'layer' done */ /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ valcrt=p[ofsq]; for (k=0; krl){ /* ci<1 */ fifo4_add(q, (long int)ofs); goto myreset; } } } } /* ci=1 set current r-CC to lbl and proceed */ while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (rcrt>rlcrt){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; // rcrt; } break; } // end reset for (k=0; k=abs(p[ofs]-p[ofsk])){ rlcrt=abs(p[ofs]-p[ofsk])-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[ofs]-p[ofsk]); if (rk>rlcrt) continue; if (rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ valcrt=p[ofsq]; for (k=0; krl){ /* ci<1 */ goto myreset2; } } } } while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=lbl; } myreset2: while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=R_BIT+1; } lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ /** * @file labelci.c * @author Pierre Soille * @date * * @details see also \cite soille2008pami */ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define BORDER_VAL 0x80000000 #define FIRST_LBL 0x00000200 #define LBL_BIT 0x7FFFFE00 #define BORDER_OR_LBL_BIT 0x8FFFFE00 #define R_BIT 0x000000FF #define NCMAX 255 /* maximum number of channels */ IMAGE *uc_labelcims(IMAGE **imap, int nc, IMAGE *imse, int ox, int oy, int oz, int rl) { /* First 2006-06-06: positive energy after IVC05 result */ /* first attempt for multichannel version */ PIX_TYPE *p[NCMAX], valcrt; IMAGE *im, *imlbl; CC_LBL_TYPE *plbl, lbl=FIRST_LBL; unsigned long int npix, i, j, ofs, ofsq, ofsk; int rk, rcrt=0, rlcrt, rtmp, prio; long int k, *shft; int c; FIFO4 *q; int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; im=imap[0]; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=nx*ny*nz; imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelcc(): not enough memory!\n"); errputstr(buf); return NULL; } pq = pqinit(NULL, 10000); /* priority queue */ if (pq == NULL){ free_image(imlbl); return NULL; } q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_pq(pq); return NULL; } n = objectpix(imse); if (n==ERROR) return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_pq(pq); free_fifo4(q); return NULL; } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); if (u32_framebox(imlbl,box,BORDER_VAL)==ERROR){ free_image(imlbl); free_pq(pq); free_fifo4(q); free((char*)shft); return NULL; } i32_arithcst(imlbl,R_BIT+1,OR_op); /* Here we go */ for (c=0;c=rtmp) rlcrt=rtmp-1; continue; } rk=abs(p[0][i]-p[0][ofsk]); for (c=1;crlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (rcrt>rlcrt){ fifo4_add(q, (long int)ofs); goto myreset; } if (prio>rcrt){ /* nth 'layer' done */ /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ for(c=0;crl){ /* ci<1 */ fifo4_add(q, (long int)ofs); goto myreset; } } } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (rcrt>rlcrt){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; } break; } // end reset for (k=0; k=rtmp){ rlcrt=rtmp-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[0][ofs]-p[0][ofsk]); for (c=1;crlcrt) continue; if(rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ for(c=0;crl){ /* ci<1 */ goto myreset2; } } } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; myreset2: while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=R_BIT+1; } lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i=rtmp) rlcrt=rtmp-1; continue; } rk=abs(p[0][i]-p[0][ofsk]); for (c=1;crlcrt) continue; plbl[ofsk]=rk; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } /* here we go */ if( pqpeek(pq, apqd) != NULL) rcrt=apqd[0]->prio; while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); if (plbl[ofs]&LBL_BIT) continue; if (rcrt>rlcrt){ fifo4_add(q, (long int)ofs); goto myreset; } if (prio>rcrt){ /* nth 'layer' done */ /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ for(c=0;crl){ /* ci<1 */ fifo4_add(q, (long int)ofs); goto myreset; } } } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; rcrt=prio; if (plbl[ofs]&LBL_BIT) continue; } fifo4_add(q, (long int)ofs); if (rcrt>rlcrt){ /* reset */ myreset: for (j=1; jsize; j++){ if (pq->d[j] != NULL){ ofsq=pq->d[j]->offset; if(!(plbl[ofsq]&LBL_BIT)){ plbl[ofsq]=R_BIT+1; } free((char*) (pq->d[j]) ); } } pq->size=1; while ( (ofsq=fifo4_remove(q)) != 0){ if (plbl[ofsq]&LBL_BIT){ printf("SHOULD NEVER HAPPEN!\n"); continue; } plbl[ofsq]=R_BIT+1; } break; } // end reset for (k=0; k=rtmp){ rlcrt=rtmp-1; if (rcrt>rlcrt) goto myreset; } } continue; } rk=abs(p[0][ofs]-p[0][ofsk]); for (c=1;crlcrt) continue; if(rkprio = rk; pqd->offset= (long int)ofsk; pqmininsert(pq, pqd); } } } /* first look for largest edge weight in CC (wmax) */ fifo4_lookreset(q); while ( (ofsq=fifo4_look(q)) != 0){ for(c=0;crl){ /* ci<1 */ goto myreset2; } } } } } while ( (ofsq=fifo4_remove(q)) != 0) plbl[ofsq]=lbl; myreset2: while ( (ofsq=fifo4_remove(q)) != 0){ plbl[ofsq]=R_BIT+1; } lbl++; } } free_pq(pq); free_fifo4(q); free((char*)shft); for (i=0;i. ***********************************************************************/ #include #include #include #ifdef OPENMP #include #endif #include "miallib.h" #include "fifo.h" /** \addtogroup group_label * @{ */ /* by Pierre Soille */ /* first: 20100509 */ /* generalise with arbitrary neighbourhood instead of simply graph */ #include "uc_def.h" IMAGE *uc_labelvertex(IMAGE *im, int alpha, int graph) { /* set each vertex to the number of adjacent vertices that are within alpha */ long int shft[27]; long int x, y, z, nx, ny, nz, k; unsigned long int ofs; PIX_TYPE *p; IMAGE *imout; UCHAR *pout; p=(PIX_TYPE *)GetImPtr(im); ny=GetImNy(im); nx=GetImNx(im); nz=GetImNz(im); imout=create_image(t_UCHAR, nx, ny, nz); if (imout==NULL){ (void)sprintf(buf,"uc_labelvertex(): not enough memory!\n"); errputstr(buf); return NULL; } pout=(UCHAR *)GetImPtr(imout); if (set_seq_shift(nx, ny, nz, graph, shft) == ERROR){ free_image(imout); return NULL; } for(z=MIN(nz-1,1); zp[ofs]) && (max>p[ofs+shft[k]]) ){ flagmax=0; max=p[ofs+shft[k]]; } } if (flagmin) min=p[ofs]; if (flagmax) max=p[ofs]; switch (type) { case 0: pout[ofs]=p[ofs]-min; break; case 1: pout[ofs]=max-p[ofs]; break; case 2: if (flagmin) pout[ofs]=max-p[ofs]; else if (flagmax) pout[ofs]=p[ofs]-min; else pout[ofs]=MIN(p[ofs]-min,max-p[ofs]); break; } } } } return imout; } #include "uc_undef.h" IMAGE *vertexseparation(IMAGE *im, int graph, int type) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_vertexseparation(im, graph, type)); break; default: (void)sprintf(buf,"vertexseparation(): invalid pixel type (%d)\n", GetImDataType(im)); errputstr(buf); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/lerodil.c000066400000000000000000001065101467232417700173620ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Erosion and dilation along arbitrary (periodic) line segments \cite soille-breen-jones96 * @author Pierre Soille */ #include #include #include #ifdef OPENMP #include #endif #include "math.h" #include "miallib.h" #ifndef min #define min(a,b) ((a)<(b)?(a):(b)) #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif /** \addtogroup group_erodil * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" void generic_genfminomp(PIX_TYPE *f, long int *p, int nx, int K, int nxmax) { /* ** f: input array. Where 1st member is *(f+p[0]) and 2nd member is = *(f+p[1]) etc. ** g: forward array ** h: backward array ** p: array of offsets ** nx: the number of elements in each array ** K: the extent of mask */ unsigned i=1,j,k,r,r1; long int index=0; PIX_TYPE *g, *h, *gori, *hori; /* allocate memory for g and h arrays */ g = gori = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nxmax); h = hori = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nxmax); if(!(K%2)) K += 1; /* Enforce odd extent */ k = nx/K; r1 = nx%K; /* do forward array */ for(j=0;j>1)){ g--; for(i=0;i>1; g+=r; if(nx <= K){ r1 = nx - r - 1; for(i=0;i>1)){ g--; for(i=0;i>1; g+=r; if(nx <= K){ r1 = nx - r - 1; for(i=0;i>1)){ g--; for(i=0;i>1; g+=r; if(nx <= K){ r1 = nx - r - 1; for(i=0;i>1)){ g--; for(i=0;i>1; g+=r; if(nx <= K){ r1 = nx - r - 1; for(i=0;i>1)){ g--; for(i=0;i>1; g+=r; if(nx <= K){ r1 = nx - r - 1; for(i=0;i OK a une translation pres */ { /* ** x0: x coor. of origin ** y0: y coor. of origin ** dx: offset in x ** dy: offset in y ** p: pointer to shifts of the line (Bres. or Period.) ** pb: pointer to shifts of the Bres. line ** rlc: pointer to run length coding of the Bres. line ** ncol: number of columns of the image ** n: number of pixels in the Bres. line ** period: periodicity of points along the Bres. line */ int ix,iy,inc,plotx,ploty,x,y,i,plot,sdx,sdy,flag; int *px, *py, *pxtmp, *pytmp; px = (int*)calloc(sizeof(int),(unsigned)n); py = (int*)calloc(sizeof(int),(unsigned)n); pxtmp = px; pytmp = py; ix = abs(dx); iy = abs(dy); inc = ix > iy ? ix : iy; sdy = dy > 0 ? 1: dy == 0? 0: -1; sdx = dx > 0 ? 1: dx == 0? 0: -1; plotx = x0; ploty = y0; x = y = 0; flag = abs(dx) >= abs(dy) ? 0 : 1; *px++ = plotx; *py++ = ploty; *p++ = plotx+ncol*ploty; *pb++ = plotx+ncol*ploty; *rlc += 1; for(i=0;i inc){ plot = 1; x -= inc; plotx += sdx; } if(y > inc){ plot = 1; y -= inc; ploty += sdy; } if(plot){ if (flag && (plotx==*(px-1))) /* vert. */ *rlc += 1; else if (!flag && (ploty==*(py-1))) *rlc += 1; /* hori. */ else{ /* diag. */ rlc++; *rlc += 1; } *px++ = plotx; *py++ = ploty; *pb++ = plotx+ncol*ploty; if((i%period)==0){ *p++ = plotx+ncol*ploty; } } /* (void)sprintf(buf,"i=%d\t*p=%d\tplotx=%d\tploty=%d\n", i,*(p-1),plotx,ploty); */ } free((char *)pxtmp); free((char *)pytmp); } /* full omp (all regions not only constant) 20120426: pot Christina+ Jacek */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_glinemin(PIX_TYPE *f, int ncol, int nlin, int dx,int dy, int k, int line_type) { /* ** f: image data as a 1D array ** ncol: number of image columns ** nlin: number of image lines ** dx: used for slope definition ** dy: slope=dy/dx ** k: extent of the SE in pixels ** line_type: 0 for BRESENHAM and 1 for PERIODIC ** 20120427: the load is not equal for all threads in the non-constant regions but the use of schedule(dynamic) is decreasing substantially the speed. It has therefore been removed after initial consideration. */ PIX_TYPE *ftmp; long int *p, *pb, *ptmp, *pbtmp; int *rlc; int inc, incx, incy, var; int pxf = 0, pyf = 0, nx, i, j, l, l1, l2, la; int period, cycle, j0, rj; #ifdef XLDEBUG long int start; start = clock(); #endif /* set coordinates of p array */ if (dx<0){ dx = -dx; dy = -dy; } if (abs(dx) >= abs(dy)){ if (dx==0) return(NO_ERROR); incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; var = 1; if (dy > 0){ /* vert. translation */ pxf = nx-1; var = -1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); var = ncol; } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); var = -ncol; } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); pb = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); if (line_type==BRES) period = 1; else /* periodic line */ period = max(abs(dx),abs(dy)); traceline(pxf,pyf,dx,dy,p,pb,rlc,ncol,nx,period); /* update rlc with running sums for omp version 20120426 */ for(i=1;i= 0 ? l1:l2; (void) sprintf(buf, "generic_glinemin(): la=%d l1=%d l2=%d\n\n", la, l1, l2); errputstr(buf); #ifdef OPENMP #pragma omp parallel for private(i,j,ftmp,j0,rj,cycle) #endif for (i=0; i1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfminomp(ftmp+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle1){ pbtmp=pb+rlc[i-la]; ftmp=f+rlc[i-la]*var; } else{ ptmp=p+rlc[i-la]; ftmp=f+(i-la)*inc; } j=rlc[i]-rlc[i-la]; j0=(j+period-1)/period; generic_genfminomp(f,p,j0,k,nx); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfminomp(ftmp+*(pbtmp+cycle)-*pbtmp,ptmp,j0,k,nx); } for (cycle=rj+1; cycle1) && (la1){ for (cycle=1; cycle<=rj; cycle++){ generic_genfminomp(ftmp+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle1){ pbtmp=pb+rlc[l+i]; ftmp=f+rlc[l+i]*var; } else{ ptmp=p+rlc[l+i]; ftmp=f+i*inc; } j=rlc[nx-1]-rlc[l+i]; j0=(j+period-1)/period; generic_genfminomp(ftmp,ptmp,j0,k,nx); if (period>1){ rj=(j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfminomp(ftmp+*(pbtmp+cycle)-*pbtmp,ptmp,j0,k,nx); } for (cycle=rj+1; cycle= abs(dy)){ if (dx==0) return(NO_ERROR); incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; var = 1; if (dy > 0){ /* vert. translation */ pxf = nx-1; var = -1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); var = ncol; } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); var = -ncol; } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); pb = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); if (line_type==BRES) period = 1; else /* periodic line */ period = max(abs(dx),abs(dy)); traceline(pxf,pyf,dx,dy,p,pb,rlc,ncol,nx,period); /* allocate memory for g and h arrays */ // not used in omp version //g = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); //h = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); /* erode/dilate the whole image */ ptmp = p; pbtmp = pb; inc = incx + ncol*incy; f -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; for (i=0; i1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ //generic_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); generic_genfminomp(f+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j += rlc[i]; j0 = (j+period-1)/period; //generic_genfmin(f,g,h,p,j0,k); generic_genfminomp(f,p,j0,k,nx); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ //generic_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); generic_genfminomp(f+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ //generic_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); generic_genfminomp(ftmp+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j0 = (j+period-1)/period; //generic_genfmin(f,g,h,p,j0,k); generic_genfminomp(f,p,j0,k,nx); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ //generic_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); generic_genfminomp(f+*(pb+cycle)-*pb,p,j0,k,nx); } for (cycle=rj+1; cycle= abs(dy)){ if (dx==0) return(NO_ERROR); incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; var = 1; if (dy > 0){ /* vert. translation */ pxf = nx-1; var = -1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); var = ncol; } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); var = -ncol; } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); pb = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); if (line_type==BRES) period = 1; else /* periodic line */ period = max(abs(dx),abs(dy)); traceline(pxf,pyf,dx,dy,p,pb,rlc,ncol,nx,period); /* allocate memory for g and h arrays */ g = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); h = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); /* erode/dilate the whole image */ ptmp = p; pbtmp = pb; inc = incx + ncol*incy; f -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; for (i=0; i1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j += rlc[i]; j0 = (j+period-1)/period; us_genfmin(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j0 = (j+period-1)/period; us_genfmin(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmin(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle= abs(dy)){ if (dx==0) return(NO_ERROR); incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; var = 1; if (dy > 0){ /* vert. translation */ pxf = nx-1; var = -1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); var = ncol; } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); var = -ncol; } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); pb = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); if (line_type==BRES){ period = 1; } else{ /* periodic line */ period = max(abs(dx),abs(dy)); } traceline(pxf, pyf, dx, dy, p, pb, rlc, ncol, nx, period); /* allocate memory for g and h arrays */ g = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); h = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); /* erode/dilate the whole image */ ptmp = p; pbtmp = pb; inc = incx + ncol*incy; f -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; for (i=0; i1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j += rlc[i]; j0 = (j+period-1)/period; generic_genfmax(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j0 = (j+period-1)/period; generic_genfmax(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ generic_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle= abs(dy)){ if (dx==0) return(NO_ERROR); incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; var = 1; if (dy > 0){ /* vert. translation */ pxf = nx-1; var = -1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); var = ncol; } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); var = -ncol; } } p = (long int*)calloc(sizeof(long int),(unsigned)nx); pb = (long int*)calloc(sizeof(long int),(unsigned)nx); rlc = (int*)calloc(sizeof(int),(unsigned)nx); if (line_type==BRES){ period = 1; } else{ /* periodic line */ period = max(abs(dx),abs(dy)); } traceline(pxf, pyf, dx, dy, p, pb, rlc, ncol, nx, period); /* allocate memory for g and h arrays */ g = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); h = (PIX_TYPE*)calloc(sizeof(PIX_TYPE),(unsigned)nx); /* erode/dilate the whole image */ ptmp = p; pbtmp = pb; inc = incx + ncol*incy; f -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; for (i=0; i1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j += rlc[i]; j0 = (j+period-1)/period; us_genfmax(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle1){ pb += rlc[l]; f += rlc[l]*var; } else{ p += rlc[l]; f += inc; } j -= rlc[l++]; j0 = (j+period-1)/period; us_genfmax(f,g,h,p,j0,k); if (period>1){ rj = (j+period-1)%period; for (cycle=1; cycle<=rj; cycle++){ us_genfmax(f+*(pb+cycle)-*pb,g,h,p,j0,k); } for (cycle=rj+1; cycle. ***********************************************************************/ /*************************************************************************** linepool.c - description ------------------- Linepool for storing all lines which are used in order to vectorize the segmented image begin : Mon May 17 2004 ***************************************************************************/ #include #include #define NO_BUF #include "borderdetection.h" /* * freeLinePool: free lines in line pool and linepool themselves * * Parameters: * * linepool pointer to linepool * * Return values: * * none */ void freeLinePool(struct LINEPOOL * linepool) { int i; if (linepool==NULL){ return; } struct LINE ** lines; lines = linepool->lines; for(i=0; isize; i++){ freeLine(lines[i]); } free(linepool->lines); } /* * addLineToLinePool: add line to linepool * * Parameters: * * linepool pointer to linepool * * line pointer to line which shall be added to linepool * * Return values: * * linepool if everythin is ok => pointer to linepool * * NULL if error occured */ struct LINEPOOL *addLineToLinePool(struct LINEPOOL * linepool, struct LINE * line) { int newSize, crtPos; struct LINE ** tmpLines; if(!linepool || !line){ return NULL; } if(linepool->size == linepool->crtPos){ newSize = linepool->size + linepool->step; if((tmpLines = realloc(linepool->lines, sizeof(struct LINE *) * newSize))==NULL){ return NULL; } linepool->lines=tmpLines; linepool->size=newSize; } tmpLines = linepool->lines; crtPos = linepool->crtPos; tmpLines[crtPos++]=line; linepool->crtPos=crtPos; return linepool; } /* * initLinePool: initializes linepool * * Parameters: * * linepool pointer to linepool * * int initialize size of linepool * * Return values: * * linepool if everythin is ok => pointer to linepool * * NULL if error occured */ struct LINEPOOL * initLinePool(struct LINEPOOL * linepool, int size) { struct LINE ** lines; if((lines=calloc(size, sizeof(struct LINE *)))==NULL){ printf("Not enough memory - initLinePool()!!!\n"); return NULL; } linepool->size = linepool->step = size; linepool->crtPos = 0; linepool->lines = lines; return linepool; } /* * getLine: return the line, specified with 3 points, of the linepool. * * Parameters: * * linepool pointer to linepool * * startX x coordinate from start point * * startY y coordinate from start point * * middleX x coordinate from middle point * * middleY y coordinate from middle point * * endX x coordinate from end point * * endY Y coordinate from end point * * Return values: * * line if line is in line point => pointer to line * * NULL if line is not in linepool */ struct LINE *getLine(struct LINEPOOL * linepool, int startX, int startY, int middleX, int middleY, int endX, int endY) { int i,j; struct LINE * crtLine; struct POINT * startPoint, * endPoint, * crtPoint; for(i=(linepool->crtPos)-1; i>=0; i--){ crtLine=linepool->lines[i]; if(crtLine!=NULL){ if(crtLine->crtPos>2){ startPoint=crtLine->points[0]; endPoint=crtLine->points[(crtLine->crtPos)-1]; //check whether start and end points corresponds to the attributes of the function if((startPoint->x==startX && startPoint->y==startY && endPoint->x==endX && endPoint->y==endY) || (startPoint->x==endX && startPoint->y==endY && endPoint->x==startX && endPoint->y==startY)){ for(j=crtLine->crtPos-1; j>=1;--j){ crtPoint=crtLine->points[j]; if(crtPoint->x==middleX && crtPoint->y==middleY){ return crtLine; } } } } } } return NULL; } /* * getLine: return the line, specified with 2 points, of the linepool. * * Parameters: * * linepool pointer to linepool * * startX x coordinate from start point * * startY y coordinate from start point * * endX x coordinate from end point * * endY Y coordinate from end point * * Return values: * * line if line is in line point => pointer to line * * NULL if line is not in linepool */ struct LINE *getLineWith2Points(struct LINEPOOL * linepool, int startX, int startY, int endX, int endY){ int i; struct LINE * crtLine; struct POINT * startPoint, * endPoint; for(i=(linepool->crtPos)-1; i>=0; i--){ crtLine=linepool->lines[i]; //line must have exactely 2 Points if(crtLine!=NULL){ if(crtLine->crtPos==2){ startPoint=crtLine->points[0]; endPoint=crtLine->points[1]; //check whether start and end points corresponds to the attributes of the function if((startPoint->x==startX && startPoint->y==startY && endPoint->x==endX && endPoint->y==endY) || (startPoint->x==endX && startPoint->y==endY && endPoint->x==startX && endPoint->y==startY)){ return crtLine; } } } } return NULL; } jeolib-miallib-1.1.6/core/c/ll_def.h000066400000000000000000000021411467232417700171550ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for long long int data types */ #define FLOATING 0 #define SIGNED 1 #define SUM_TYPE long long int #define OVFL_TEST 0 #define PIX_TYPE LINT32 #define PIX_MIN LINT32_MIN #define PIX_MAX LINT32_MAX #define PIX_MSB 0x8000000000000000 jeolib-miallib-1.1.6/core/c/ll_undef.h000066400000000000000000000020311467232417700175160ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef FLOATING #undef SIGNED #undef SUM_TYPE #undef OVFL_TEST #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MSB jeolib-miallib-1.1.6/core/c/mblincomb.c000066400000000000000000000122131467232417700176660ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2013-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #ifdef OPENMP #include #endif /* First: 20131113 by Pierre Soille for haze removal in L7 based tasselled cap transformation (experimental code, not finalised) */ #include "f_def.h" #define NCMAX 255 /* maximum number of channels */ ERROR_TYPE f_mblincomb(IMAGE **imap, int nc, IMAGE *matrix) { PIX_TYPE *imptr[NCMAX]; double *pm, pocrt[NCMAX]; long int k, npix, ofs; int i, j; if (GetImDataType(matrix) != t_DOUBLE){ sprintf(buf, "f_mblincomb() error: the matrix image must be of type t_DOUBLE\n"); errputstr(buf); return ERROR; } for(k=0;k. ***********************************************************************/ /** * @file mcisrg.c * @author Dominik Brunner and Pierre Soille * @date * * @details see also \cite brunner-soille2007 * */ /*************************************************************************** mcisrg.c - description mcisrg stands for multi channel improved seeded region growing algorithm. This is a adapted version for multispectral images of the algorithm introduced by Andrew Mehnert and Paul Jackway ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #define DELTA_MAX DOUBLE_MAX #include #include #include "miallib.h" #include "fifo.h" #include "pqueueExact.h" #include "regionMean.h" #include "math.h" #include "base.h" #include "mcisrg.h" extern int us_rmAddValueOriginal(struct regionMean *rm, IMAGE **imap, long int offset); extern int us_rmAddValue(struct regionMean *rm, IMAGE **imap, long int offset); extern double us_rmGetDistanceToRM(struct regionMean *rm, IMAGE **imap, long int offset); extern double us_rmGetDistanceToOriginalRM(struct regionMean *rm, IMAGE **imap, long int offset); /** \addtogroup group_seg * @{ */ /* * mcisrg: multichannel improved seeded region growing algorithm. * * Parameters: * * IMAGE **imap: multichannel image * * int nc: number of channels * * IMAGE *seedsIm: image of seeds * * int graph: graph (neighbour relationship) * * long int regionNumber: number of Regions * * version version of mcisrg algorithm. Versions are * 0 (compare to whole region) * 1 (compare to original seeds) * 2 (compare to pixel neighbours) * * * Return values: * * ERROR if error occured * * NO_ERROR if no error occured */ #include "uc_def.h" ERROR_TYPE uc_mcisrg(IMAGE **imap, int nc, IMAGE *seedsIm, int graph, long int regionNumber, int version) { long int l, k, shft[27], offset, current, ofsk, ofsj, nxny; double delta, deltacrt=0.0, hprior,j; float mean; PIX_TYPE **pIm; LBL_TYPE *pSeeds, *pSeedsCrt, *pSeedsK, *pSeedsO, *pSeedsO2, val=0, crtSeedValue; FIFO4 *nhq, *hq; struct pqueue *pq; struct regionMean * rm, crtRegionMean; int n, nx, ny; int box[6]; int i; char fname[50]; PQDATUM apqd[1]; struct node *pqd; // initilize box for frame which shall be added in order to solve // problem with neighbours box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; // make checks on datatypes, and wheather dimensions of images in // imap and labelIm fit together if ((nc < 1) || (regionNumber < 1)){ (void)sprintf(buf,"mcisrg(): invalid nc or regionNumber\n"); errputstr(buf); return ERROR; } //make check whether version has an authorised value if(!((version == WHOLE_REGION) || (version == ORIGINAL_SEED) || (version == PIXEL_NEIGHBOUR))){ printf("parameter value is %i. Only 0,1,2 are allowed.\n", version); return ERROR; } for (i = 0; i < nc; i++){ if ((GetImNx(imap[i]) != GetImNx(seedsIm)) || (GetImNy(imap[i]) != GetImNy(seedsIm)) \ || (GetImDataType(imap[i]) != GetImDataType(imap[0])) ){ (void)sprintf(buf,"mcisrg(): at least one channel is not matching the image of seeds (different size)\n"); errputstr(buf); return ERROR; } } if (GetImDataType(seedsIm) != t_LBL_TYPE){ return ERROR; } //add border for (i = 0; i < nc; i++){ if (generic_addframebox(imap[i], box, BORDER) == ERROR){ return ERROR; } } if (u32_addframebox(seedsIm, box, BORDER) == ERROR){ return ERROR; } pIm = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE *)); nx = GetImNx(seedsIm); ny = GetImNy(seedsIm); nhq = create_fifo4((nx*ny)/100L); /* neighbouring queue */ if (nhq == NULL){ free((PIX_TYPE **)pIm); return ERROR; } hq = create_fifo4((nx*ny)/100L); /* holding queue */ if (hq == NULL){ free_fifo4(nhq); free((PIX_TYPE **)pIm); return ERROR; } pq = (struct pqueue *)pqExactInit(NULL, 100); /* priority queue */ if (pq == NULL){ free_fifo4(nhq); free_fifo4(hq); free((PIX_TYPE **) pIm); return ERROR; } // add frameboxes so that neighbours are always in image for (i = 0; i < nc; i++){ pIm[i]=(PIX_TYPE *) GetImPtr(imap[i]); } if (set_seq_shift(GetImNx(seedsIm), GetImNy(seedsIm), GetImNz(seedsIm), graph, shft) == ERROR){ free_fifo4(nhq); free_fifo4(hq); free((PIX_TYPE **) pIm); return ERROR; } pSeeds = (LBL_TYPE *) GetImPtr(seedsIm); //update nx,ny,nz after adding border nx = GetImNx(seedsIm); ny = GetImNy(seedsIm); //initialize regionMean and initialise the neighbouring queue NHQ //(with their offset to origin) rm = (struct regionMean *) (calloc(regionNumber+1, sizeof(struct regionMean))); for(i=0; i=SEED){ uc_rmAddValueOriginal(rm+(*pSeedsCrt), imap, offset); } else if ((*pSeedsCrt)==NOSEED){ /* usually, there will be less NOSEED then SEED pixels */ for (k=0; k < graph; k++){ current = offset + shft[k]; pSeedsO = pSeeds +current; if (*pSeedsO >= SEED){ fifo4_add(nhq, (long int) offset); *(pSeedsCrt)=IN_NHQ; break; } } } } sprintf(fname,"/tmp/mcisrgBEFORE.tif"); write_tiff(imap[0], fname); /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqExactPeek(pq, apqd) != NULL) ){ //examine the neighbours of pixels in the neighbouring holding queue while ( (offset = (long int)fifo4_remove(nhq)) ){ delta=DELTA_MAX; for (k=0; k < graph; k++){ ofsk=offset+shft[k]; pSeedsO=pSeeds + ofsk; crtSeedValue=*pSeedsO; if (crtSeedValue>=SEED){ //switch for different versions of algorithm if(version==PIXEL_NEIGHBOUR){ clearRegionMean(&crtRegionMean); uc_rmAddValue(&crtRegionMean, imap, ofsk); for(l=0; lprio = (unsigned int) delta; pqd->val = val; pqd->offset= offset; pqExactMinInsert(pq, pqd); *(pSeeds+offset) = IN_PQ; } if (pqExactPeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqExactMinRemove(pq, apqd); offset=apqd[0]->offset; pSeedsO=pSeeds+offset; if (*pSeedsO == IN_PQ){ *pSeedsO=(*apqd)->val;//assign the region label to the pixel fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while (pqExactPeek(pq, apqd) != NULL) { if (((*apqd)->prio) != hprior) break; pqExactMinRemove(pq, apqd); offset=apqd[0]->offset; pSeedsO=pSeeds+offset; if (*pSeedsO == IN_PQ){ *pSeedsO=(*apqd)->val;//assign the region label to the pixel fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ((offset = (long int)fifo4_remove(hq)) ){ pSeedsO = pSeeds+offset; //update color information uc_rmAddValue(rm+(*pSeedsO), imap, offset); for (k=0; k < graph; k++){ pSeedsK = pSeedsO + shft[k]; if ((*pSeedsK == NOSEED) || (*pSeedsK == IN_PQ)){ fifo4_add(nhq, (long int)(offset+shft[k])); *pSeedsK=IN_NHQ; } } } } sprintf(fname,"/tmp/mcisrgAFTER.tif"); write_tiff(imap[0], fname); //admit new color value to each channel in image nxny=nx*ny; for(offset=0; offsetmeanValue)+n); if(modf((double)mean, &j)>=0.5) *(pIm[n]+offset) = (PIX_TYPE) ceil((double) mean); else *(pIm[n]+offset) = (PIX_TYPE) floor((double) mean); } } for(i=0; i=SEED){ us_rmAddValueOriginal(rm+(*pSeedsCrt), imap, offset); } else if ((*pSeedsCrt)==NOSEED){ /* usually, there will be less NOSEED then SEED pixels */ for (k=0; k < graph; k++){ current = offset + shft[k]; pSeedsO = pSeeds +current; if (*pSeedsO >= SEED){ fifo4_add(nhq, (long int) offset); *(pSeedsCrt)=IN_NHQ; break; } } } } sprintf(fname,"/tmp/mcisrgBEFORE.tif"); write_tiff(imap[0], fname); /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqExactPeek(pq, apqd) != NULL) ){ //examine the neighbours of pixels in the neighbouring holding queue while ( (offset = (long int)fifo4_remove(nhq)) ){ delta=DELTA_MAX; for (k=0; k < graph; k++){ ofsk=offset+shft[k]; pSeedsO=pSeeds + ofsk; crtSeedValue=*pSeedsO; if (crtSeedValue>=SEED){ //switch for different versions of algorithm if(version==PIXEL_NEIGHBOUR){ clearRegionMean(&crtRegionMean); us_rmAddValue(&crtRegionMean, imap, ofsk); for(l=0; lprio = (unsigned int) delta; pqd->val = val; pqd->offset= offset; pqExactMinInsert(pq, pqd); *(pSeeds+offset) = IN_PQ; } if (pqExactPeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqExactMinRemove(pq, apqd); offset=apqd[0]->offset; pSeedsO=pSeeds+offset; if (*pSeedsO == IN_PQ){ *pSeedsO=(*apqd)->val;//assign the region label to the pixel fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while (pqExactPeek(pq, apqd) != NULL) { if (((*apqd)->prio) != hprior) break; pqExactMinRemove(pq, apqd); offset=apqd[0]->offset; pSeedsO=pSeeds+offset; if (*pSeedsO == IN_PQ){ *pSeedsO=(*apqd)->val;//assign the region label to the pixel fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ((offset = (long int)fifo4_remove(hq)) ){ pSeedsO = pSeeds+offset; //update color information us_rmAddValue(rm+(*pSeedsO), imap, offset); for (k=0; k < graph; k++){ pSeedsK = pSeedsO + shft[k]; if ((*pSeedsK == NOSEED) || (*pSeedsK == IN_PQ)){ fifo4_add(nhq, (long int)(offset+shft[k])); *pSeedsK=IN_NHQ; } } } } sprintf(fname,"/tmp/mcisrgAFTER.tif"); write_tiff(imap[0], fname); //admit new color value to each channel in image nxny=nx*ny; for(offset=0; offsetmeanValue)+n); if(modf((double)mean, &j)>=0.5) *(pIm[n]+offset) = (PIX_TYPE) ceil((double) mean); else *(pIm[n]+offset) = (PIX_TYPE) floor((double) mean); } } for(i=0; i. ***********************************************************************/ /*************************************************************************** mcisrg.h - description ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #ifndef init_mcisrg #define init_mcisrg #define WHOLE_REGION 0x00 #define ORIGINAL_SEED 0x01 #define PIXEL_NEIGHBOUR 0x02 ERROR_TYPE mcisrg(IMAGE **imap, int nc, IMAGE *seedsIm, int connectivity, long int regionNumber, int version); #endif jeolib-miallib-1.1.6/core/c/miallib.h000066400000000000000000000451031467232417700173460ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* ** Header file for image analysis routines ** by Pierre Soille@ec.europa.eu 1988--2018 */ #ifndef _MIALLIB_H #define _MIALLIB_H 1 #ifdef PYTHON #include #define printf PySys_WriteStdout #endif #include #include #include "mialtypes.h" #include "config_miallib.h" /* adjust to local system */ #define BITPERCHAR 8 #define BITPERSHORT 16 #define BITPERINT32 32 #define BITPERINT64 64 #define BITPERFLOAT 32 #define BITPERDOUBLE 64 #define BITPERWORD (sizeof(long int)*8) #define BYTEPERWORD sizeof(long int) #define BITPERBAND 8 #if _WIN32 || _WIN64 #if _WIN64 #define __WORDSIZE 64 #else #define __WORDSIZE 32 #endif #endif #if (__WORDSIZE==32) #define W_MSB 0x80000000 #elif (__WORDSIZE==64) #define W_MSB 0x8000000000000000 #endif #ifndef UCHAR_MIN #define UCHAR_MIN 0 #endif #ifndef UCHAR_MAX #define UCHAR_MAX 0xFF #endif #ifndef SHORT_MIN #define SHORT_MIN -0x8000 #endif #ifndef SHORT_MAX #define SHORT_MAX 0x7FFF #endif #ifndef INT_MIN #define INT_MIN -0x80000000 #endif #ifndef INT_MAX #define INT_MAX 0x7FFFFFFF #endif #ifndef USHORT_MIN #define USHORT_MIN 0 #endif #ifndef USHORT_MAX #define USHORT_MAX 0xFFFF #endif #ifndef INT32_MIN #define INT32_MIN -0x80000000 #endif #ifndef INT32_MAX #define INT32_MAX 0x7FFFFFFF #endif #ifndef UINT32_MIN #define UINT32_MIN 0 #endif #ifndef UINT32_MAX #define UINT32_MAX 0xFFFFFFFF #endif #ifndef INT64_MIN #define INT64_MIN -0x8000000000000000 #endif #ifndef INT64_MAX #define INT64_MAX 0x7FFFFFFFFFFFFFFF #endif #ifndef UINT64_MIN #define UINT64_MIN 0 #endif #ifndef UINT64_MAX #define UINT64_MAX 0xFFFFFFFFFFFFFFFF #endif #define MIALFLOAT_MAX ((float)3.40282346638528860e+38) #define MIALFLOAT_MIN ((float)1.40129846432481707e-45) #ifndef DOUBLE_MAX #define DOUBLE_MAX 1.797693134862315708e+308 #endif #ifndef DOUBLE_MIN #define DOUBLE_MIN 4.94065645841246544e-324 #endif /* */ #define ERROR 1 #define NO_ERROR 0 #define TRUE 1 #define FALSE 0 #ifndef PI #define PI 3.14159265358979323846 /* same as in XLISP-PLUS */ #endif /* pixel type table */ #define t_TIFFONEBITPERPIXEL 12 #define t_ONEBITPERPIXEL 0 #define t_FOURBITPERPIXEL 1 #define t_CHAR 2 /* all should be in the form e.g. uc_TYPE */ #define t_UCHAR 3 #define t_SHORT 4 #define t_USHORT 5 #define t_INT32 6 #define t_UINT32 7 #define t_INT64 8 #define t_UINT64 9 #define t_FLOAT 10 #define t_MIALFLOAT 10 #define t_DOUBLE 11 #define t_RGB 13 /* fake type, requires pixel data type=t_UCHAR */ #define t_PTR 14 #define t_UNSUPPORTED 255 #define t_LBL_TYPE 6 /* consider unsigned long int in the future*/ #define LBL_MAX INT32_MAX #define t_GENERIC 3 #define t_HST1D 6 #define t_HST2D 3 /* different types should be allowed, 3 for ACCA */ #define t_HST3D 6 #define t_LUT 10 #define t_LABEL 6 #define PLANARCONFIG_BIL 3 /* bil model (band interleaved by line) not supported by TIFF */ /* constants */ #define BOXELEM 6 /* length of a box array */ /* useful macro definitions */ #define SGN(x) (((x) < 0) ? -1 : (((x) > 0) ? 1 : 0)) #define MYSWAP(a, b, t) ( (t) = (a), (a) = (b), (b) = (t) ) #ifndef MAX #define MAX(x, y) (((x) < (y)) ? (y) : (x)) #endif #ifndef MIN #define MIN(x, y) (((x) < (y)) ? (x) : (y)) #endif #define LOOPDN(r, n) for ( (r) = (n)+1; --(r) > 0; ) #define ERR_MSG(b) (void)fprintf(stderr,(b)) #define SQ(x) ((x) * (x)) /* macro definitions for grilisp (getset.h) */ #define GetImDataType(x) ((x)->DataType) /* data type of a pixel */ #define GetImPtr(x) ((x)->p_im) /* pointer to the first pixel */ #define GetImNx(x) ((unsigned long int)(x)->nx) #define GetImNy(x) ((unsigned long int)(x)->ny) #define GetImNz(x) ((unsigned long int)(x)->nz) #define GetImNlin(x) ((unsigned long int)(x)->nz * (x)->ny) #define GetImNPix(x) ((unsigned long int)(x)->nx * (x)->ny * (x)->nz) #define GetImNPixPerPlane(x) (((unsigned long int)(x)->nx) * (x)->ny) #define GetImNByte(x) ((unsigned long int)(x)->NByte) #define GetImCenter(x) ((x)->center) #define GetImVol(x) ((x)->vol) /* must call volume() before */ #define GetImLut(x) ((x)->lut) /* other image macro definitions */ #define IsImInteger(x) (GetImDataType(x)!=10 || GetImDataType(x)!=11) #define GetImMin(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (val) = (x)->umin.uc_val; \ break; \ case t_USHORT: \ (val) = (x)->umin.us_val; \ break; \ case t_SHORT: \ (val) = (x)->umin.s_val; \ break; \ case t_INT32: \ (val) = (x)->umin.i32_val; \ break; \ case t_UINT32: \ (val) = (x)->umin.u32_val; \ break; \ case t_INT64: \ (val) = (x)->umin.i64_val; \ break; \ case t_UINT64: \ (val) = (x)->umin.u64_val; \ break; \ case t_FLOAT: \ (val) = (x)->umin.f_val; \ break; \ case t_DOUBLE: \ (val)= (x)->umin.d_val; \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in GetImMin \ macro\n"); \ } #define GetImMax(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (val) = (x)->umax.uc_val; \ break; \ case t_USHORT: \ (val) = (x)->umax.us_val; \ break; \ case t_SHORT: \ (val) = (x)->umax.s_val; \ break; \ case t_INT32: \ (val) = (x)->umax.i32_val; \ break; \ case t_UINT32: \ (val) = (x)->umax.u32_val; \ break; \ case t_INT64: \ (val) = (x)->umax.i64_val; \ break; \ case t_UINT64: \ (val) = (x)->umax.u64_val; \ break; \ case t_FLOAT: \ (val) = (x)->umax.f_val; \ break; \ case t_DOUBLE: \ (val)= (x)->umax.d_val; \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in GetImMax \ macro\n"); \ } #define SetImDataType(x, val) ((x)->DataType = (val)) #define SetImPtr(x, val) ((x)->p_im = (void *)(val)) #define SetImNByte(x, val) ((x)->NByte = (val)) #define SetImNx(x, val) ((x)->nx = (val)) #define SetImNy(x, val) ((x)->ny = (val)) #define SetImNz(x, val) ((x)->nz = (val)) #define SetImCenter(x, val) ((x)->center = (val)) #define SetImVol(x,val) ((x)->vol = (VOL_TYPE)(val)) #define SetImLut(x, val) ((x)->lut = (val)) #define SetImMin(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (x)->umin.uc_val = (UCHAR)(val); \ break; \ case t_USHORT: \ (x)->umin.us_val = (USHORT)(val); \ break; \ case t_SHORT: \ (x)->umin.s_val = (SHORT)(val); \ break; \ case t_INT32: \ (x)->umin.i32_val = (INT32)(val); \ break; \ case t_UINT32: \ (x)->umin.u32_val = (UINT32)(val); \ break; \ case t_INT64: \ (x)->umin.i64_val = (INT64)(val); \ break; \ case t_UINT32: \ (x)->umin.u64_val = (UINT64)(val); \ break; \ case t_FLOAT: \ (x)->umin.f_val = (float)(val); \ break; \ case t_DOUBLE: \ (x)->umin.d_val = (double)(val); \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in SetImMin \ macro\n"); \ } #define SetImMax(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (x)->umax.uc_val = (UCHAR)(val); \ break; \ case t_USHORT: \ (x)->umax.us_val = (USHORT)(val); \ break; \ case t_SHORT: \ (x)->umax.s_val = (SHORT)(val); \ break; \ case t_INT32: \ (x)->umax.i32_val = (INT32)(val); \ break; \ case t_UINT32: \ (x)->umax.u32_val = (UINT32)(val); \ break; \ case t_INT64: \ (x)->umax.i64_val = (INT64)(val); \ break; \ case t_UINT64: \ (x)->umax.u64_val = (UINT64)(val); \ break; \ case t_FLOAT: \ (x)->umax.f_val = (float)(val); \ break; \ case t_DOUBLE: \ (x)->umax.d_val = (double)(val); \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in SetImMax \ macro\n"); \ } /* macro definitions for framebox */ #define BOX_1D box[0]=box[1]=1; box[2]=box[3]=box[4]=box[5]=0 #define BOX_2D box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0 #define BOX_3D box[0]=box[1]=box[2]=box[3]=box[4]=box[5]=1 /* FOR XLISP ONLY */ #if !(defined(NO_BUF)) #if (defined(XLISP)) extern char buf[]; /* used by sprintf() and stdputstr() */ extern void stdputstr(char *); /* print a message to the standard output */ extern void errputstr(char *); /* print a message to the standard error */ #else static char buf[1024]; /* used by sprintf() and stdputstr() */ extern void stdputstr(); /* print a message to the standard output */ extern void errputstr(); /* print a message to the standard error */ #endif /* #if (defined(XLISP)) */ #endif #define NO_uc_IMAGE #define NO_s_IMAGE #define NO_us_IMAGE #define NO_i32_IMAGE #define NO_u32_IMAGE #define NO_i64_IMAGE #define NO_u64_IMAGE #define NO_f_IMAGE #define NO_d_IMAGE /* external function declarations */ /* imem.c */ extern int GetImBitPerPixel(IMAGE *im); extern void free_image(IMAGE *); extern void free_lut(IMAGE *im); extern ERROR_TYPE iminfo(IMAGE *); extern IMAGE *create_image(int data_type, long int nx, int ny, int nz); extern IMAGE *copy_image(IMAGE *im); extern ERROR_TYPE copy_lut(IMAGE *im1, IMAGE *im2); extern ERROR_TYPE create_lut(IMAGE *im); extern IMAGE **create_imarray(int); extern ERROR_TYPE dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy); /* imio_gdal.c */ extern int GDAL2MIALDataType(int aGDALDataType); extern IMAGE *GDALInfoJIP(char *imfn); extern IMAGE *GDALRead(char *imfn, int band, int nXOff, int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize); /* imio.c */ extern IMAGE *read_all(char *fn, int nx, int ny, int nz, int data_type, int header_size, int pc); extern IMAGE *read_image(char *fn); extern IMAGE *read_image_to_type(char *fn, int data_type); extern ERROR_TYPE read_image_data(FILE *fp, IMAGE *im, int pc); extern ERROR_TYPE write_image_data(FILE *fp, IMAGE *im, int pc); extern ERROR_TYPE write_ColorMap_tiff(IMAGE *im, char *fn); extern ERROR_TYPE write_tiff(IMAGE *im, char *fn); extern ERROR_TYPE writeTiffOneStripPerLine(IMAGE *im, char *fn, char *desc); /* imio2.c */ extern IMAGE *GetGeoKey(char *fname, char *keyname); extern IMAGE *GetTIFFTagGeo(char *fn, char *tagname); extern IMAGE *readTiffSubset(char *fn, int x, int y, unsigned szx, unsigned szy); extern ERROR_TYPE tiffinfo(char *fn, char *field, float *val); extern IMAGE *tiffinfoJIP(char *fn); extern ERROR_TYPE read_image_data2(FILE *fp, IMAGE *im, int x, int y, int inx, int scale); extern ERROR_TYPE writeGeoTiffOneStripPerLine(IMAGE *im, char *fn, int PCSCode, double xoff, double yoff, double scale, unsigned short RasterType, int nodata_flag, int nodata_val, int metadata_flag, char *metadata_str); extern ERROR_TYPE writeMBGeoTiffOneStripPerLine(IMAGE **imap, int nc, char *fn, int PCSCode, double xoff, double yoff, double scale, unsigned short RasterType, int nodata_flag, int nodata_val, int metadata_flag, char *metadata_str); extern void print_mia_banner(); /* imstat.c */ extern IMAGE *histo1d(IMAGE *im); extern IMAGE *histo2d(IMAGE *im1, IMAGE *im2); extern IMAGE *histo3d(IMAGE *im1, IMAGE *im2, IMAGE *im3); extern IMAGE *rsum(IMAGE *im); extern IMAGE *class2d(IMAGE *im1, IMAGE *im2, IMAGE *imlut); extern IMAGE *area(IMAGE*, int, int); extern ERROR_TYPE lookup(IMAGE *, IMAGE *); extern ERROR_TYPE lookuptypematch(IMAGE *, IMAGE *); extern IMAGE *lookuprgb(IMAGE *, IMAGE *, IMAGE *, IMAGE *); extern ERROR_TYPE imequalp(IMAGE *, IMAGE *); extern ERROR_TYPE volume(IMAGE *); extern G_TYPE *min_max(IMAGE *im); extern ERROR_TYPE getfirstmaxpos(IMAGE *, unsigned long int *); extern ERROR_TYPE getmax(IMAGE *im, double *maxval); extern ERROR_TYPE getminmax(IMAGE *im, double *minval, double *maxval); extern ERROR_TYPE generic_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE s_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE u32_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE i64_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE u64_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE f_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE d_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE us_min_max(IMAGE *im, G_TYPE *pg); extern ERROR_TYPE i32_min_max(IMAGE *im, G_TYPE *pg); /* pointop.c */ extern ERROR_TYPE bitwise_op(IMAGE *im1, IMAGE *im2, int op); extern ERROR_TYPE negation(IMAGE *im); extern ERROR_TYPE arith(IMAGE *, IMAGE *, int); extern ERROR_TYPE arithcst(IMAGE *, G_TYPE, int); extern ERROR_TYPE imabs(IMAGE *), imsqrt(IMAGE *), imlog(IMAGE *), power2p(IMAGE *); extern ERROR_TYPE imatan(IMAGE *), imacos(IMAGE *), imasin(IMAGE *); extern ERROR_TYPE imatan(IMAGE *), imcos(IMAGE *), imsin(IMAGE *); extern ERROR_TYPE thresh(IMAGE *, G_TYPE, G_TYPE, G_TYPE, G_TYPE); extern ERROR_TYPE setlevel(IMAGE *im, G_TYPE gt1, G_TYPE gt2, G_TYPE gval); extern ERROR_TYPE modulo(IMAGE *im, int val); extern ERROR_TYPE complement(IMAGE *im); extern ERROR_TYPE blank(IMAGE *im, G_TYPE gval); extern ERROR_TYPE shift(IMAGE *im, int val); extern ERROR_TYPE setrange(IMAGE *im, G_TYPE gt1, G_TYPE gt2); extern ERROR_TYPE FindPixWithVal(IMAGE *, G_TYPE, unsigned long int *); extern ERROR_TYPE IsPartitionEqual(IMAGE *, IMAGE *, int *); extern ERROR_TYPE swap(IMAGE *im); extern ERROR_TYPE i32_arithcst(IMAGE *, INT32, int); extern ERROR_TYPE f_arithcst(IMAGE *, MIALFLOAT, int); extern ERROR_TYPE us_blank(IMAGE *, USHORT); extern ERROR_TYPE i32_blank(IMAGE *, INT32); extern ERROR_TYPE u32_blank(IMAGE *, UINT32); extern ERROR_TYPE f_blank(IMAGE *, MIALFLOAT); extern ERROR_TYPE generic_blank(IMAGE *, UCHAR); extern ERROR_TYPE i32_blank(IMAGE *, INT32); extern ERROR_TYPE generic_setlevel(IMAGE *im, GENERICPIX t1, GENERICPIX t2, GENERICPIX val); extern ERROR_TYPE us_setlevel(IMAGE *im, USHORT t1, USHORT t2, USHORT val); extern ERROR_TYPE s_setlevel(IMAGE *im, SHORT t1, SHORT t2, SHORT val); extern ERROR_TYPE us_setrange(IMAGE *im, USHORT t1, USHORT t2); extern ERROR_TYPE generic_thresh(IMAGE *, UCHAR, UCHAR, UCHAR, UCHAR); extern ERROR_TYPE f_thresh(IMAGE *, MIALFLOAT, MIALFLOAT, MIALFLOAT, MIALFLOAT); /* efedt.c */ extern IMAGE *sqedt(IMAGE *); extern IMAGE *iz(IMAGE *); /* format.c */ extern ERROR_TYPE to_uchar(IMAGE *); extern IMAGE *to_ushort(IMAGE *), *to_int32(IMAGE *), *to_float(IMAGE *), *to_double(IMAGE *) ; extern ERROR_TYPE dbltofloat(IMAGE *), uint32_to_float(IMAGE *); extern IMAGE *to_tiff1bitpp(IMAGE *im); extern IMAGE *to_tiff4bitpp(IMAGE *im); /* geom.c */ extern ERROR_TYPE framebox(IMAGE *im, int *box, G_TYPE gval); extern ERROR_TYPE addframebox(IMAGE *im, int *box, G_TYPE gval); extern ERROR_TYPE subframebox(IMAGE *im, int *box); extern IMAGE *getframebox(IMAGE *im, int *box); extern ERROR_TYPE setframebox(IMAGE *im, IMAGE *imframe, int *box); extern ERROR_TYPE imputop(IMAGE *im1, IMAGE *im2, int x, int y, int z, int op); extern ERROR_TYPE imputcompose(IMAGE *im1, IMAGE *imlbl, IMAGE *im2, int x, int y, int z, int val); extern IMAGE *imcut(IMAGE *im, int x1, int y1, int z1, int x2, int y2, int z2); extern IMAGE *getboundingbox(IMAGE *im); extern IMAGE *magnify(IMAGE *im, int n); extern IMAGE **rotatecoor(IMAGE *im, double theta); extern ERROR_TYPE generic_framebox(IMAGE *im, int *box, GENERICPIX gval); extern ERROR_TYPE uc_framebox(IMAGE *im, int *box, GENERICPIX gval); extern ERROR_TYPE us_framebox(IMAGE *im, int *box, USHORT gval); extern ERROR_TYPE i32_framebox(IMAGE *im, int *box, INT32 gval); extern ERROR_TYPE u32_framebox(IMAGE *im, int *box, UINT32 gval); extern ERROR_TYPE f_framebox(IMAGE *im, int *box, MIALFLOAT gval); extern ERROR_TYPE generic_addframebox(IMAGE *im, int *box, GENERICPIX gval); extern ERROR_TYPE us_addframebox(IMAGE *im, int *box, USHORT gval); extern ERROR_TYPE i32_addframebox(IMAGE *im, int *box, INT32 gval); extern ERROR_TYPE u32_addframebox(IMAGE *im, int *box, UINT32 gval); /* indexx.c */ extern void indexx(size_t , double [], size_t []); /* miscel.c */ extern IMAGE *deinterleave(IMAGE *im); /* miscel.c but not wrapped in mialisp */ extern G_TYPE getpixval(IMAGE *im, unsigned long offset); extern void swap_long(INT32 *pl); /* setshft.c */ extern ERROR_TYPE szcompat(IMAGE *, IMAGE *); extern ERROR_TYPE szgeocompat(IMAGE *, IMAGE *); extern ERROR_TYPE set_shift(long int nx, long int ny, long int nz, long int graph, long int *shift); extern ERROR_TYPE set_seq_shift(long int , long int , long int , long int , long int *); extern void set_shift_and_box(unsigned char *, int *, long int, long int, long int *); extern void set_shift_and_box_and_weight(unsigned char *im1, MIALFLOAT *im2, int *box, long int x, long int y, long int *shift, MIALFLOAT *weight); extern ERROR_TYPE setinvseqshift(long int nx, long int ny, long int nz, long int graph, long int *shft); extern long int objectpix(IMAGE *im); extern long int get_offset_first_pixel(long int nx, long int ny, long int nz, int graph); extern long int get_offset_last_pixel(long int nx, long int ny, long int nz, int graph); /* erodil.c */ extern ERROR_TYPE erode4(IMAGE *im, int ox, int oy); extern ERROR_TYPE dilate4(IMAGE *im, int ox, int oy); extern IMAGE *erode(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag); extern IMAGE *dilate(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag); extern IMAGE *volerode(IMAGE *im, IMAGE *imse, IMAGE *imweight, int ox, int oy, int oz); extern IMAGE *rank(IMAGE *im, IMAGE *imse, int rank, int ox, int oy, int oz, int trflag); /* lerodil.c */ extern ERROR_TYPE linero(IMAGE *im, int dx, int dy, int n, int line_type); extern ERROR_TYPE lindil(IMAGE *im, int dx, int dy, int n,int line_type); /* bresenham.c */ extern ERROR_TYPE plotline(IMAGE *im, int x1, int y1, int x2, int y2, int val); /* rminmax.c */ extern IMAGE *minima(IMAGE *imin, int graph); /* wshed.c */ extern IMAGE *sort_offset(IMAGE *im, IMAGE *imrsum); #endif /* miallib.h */ jeolib-miallib-1.1.6/core/c/miallib_convolve.h000066400000000000000000000033011467232417700212530ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_CONVOLVE_H #define _MIALLIB_CONVOLVE_H 1 #include "mialtypes.h" /* convolve.c */ extern IMAGE *convolve(IMAGE *im, IMAGE *imse, IMAGE *imweight, int ox, int oy, int oz); extern IMAGE *convolvedownsample(IMAGE *im, IMAGE *imse, IMAGE *imweight, int w, int ox, int oy, int oz); extern IMAGE *rsum2d(IMAGE *im); extern IMAGE *rsum3d(IMAGE *im); extern IMAGE *rsumsq2d(IMAGE *im); extern IMAGE *mean2d(IMAGE *im, int width); extern IMAGE *mean2dse(IMAGE *im, IMAGE *imse, int ox, int oy); extern IMAGE *variance2dse(IMAGE *im, IMAGE *imse, int ox, int oy); extern IMAGE *squarevol(IMAGE *im, int k, int ox, int oy); extern ERROR_TYPE azimuth(IMAGE *ix, IMAGE *iy); extern ERROR_TYPE mapori(IMAGE *i0, int ox, int oy); /* phase_correlation.c */ extern IMAGE *phase_correlation(IMAGE *im, IMAGE *im_template); #endif /* miallib_CONVOLVE.h */ jeolib-miallib-1.1.6/core/c/miallib_dem.h000066400000000000000000000037771467232417700202060ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_DEM_H #define _MIALLIB_DEM_H 1 #include "mialtypes.h" /* flow.c*/ extern IMAGE *d8(IMAGE *im); extern IMAGE *slope8(IMAGE *im); extern IMAGE *flow(IMAGE *imin, int graph); extern IMAGE *flownew(IMAGE *imin, IMAGE *imdir, int graph); extern IMAGE *cda(IMAGE *dir, int graph); extern IMAGE *stratify(IMAGE *cda, IMAGE *thresh, IMAGE *dir); extern IMAGE *dinf(IMAGE *im); extern IMAGE *cdainf(IMAGE *dir); extern IMAGE *slopeinf(IMAGE *im); extern ERROR_TYPE dir(IMAGE *im, int graph); extern ERROR_TYPE cboutlet(IMAGE *outlet, IMAGE *d8); extern ERROR_TYPE cbconfluence(IMAGE *outlet, IMAGE *d8); extern ERROR_TYPE strahler(IMAGE *d8); /* aflood.c */ extern IMAGE *aflood(IMAGE *iml, IMAGE *imr, int graph, int maxfl); /* fillocarve.c */ extern IMAGE *fillocarve(IMAGE *iml, IMAGE *imr, int graph, int maxfl, int flag); /* flatdir.c */ extern IMAGE *FlatDir(IMAGE *flat, IMAGE *im, int graph); extern ERROR_TYPE FlatIGeodAFAB(IMAGE *flat, IMAGE *im, int graph); /* htop.c */ extern IMAGE *htop(IMAGE *dem, IMAGE *d8); /* shade.c */ extern IMAGE *shade(IMAGE *im, int dir); extern IMAGE *LineDilate3D(IMAGE *im, float dh); #endif /* miallib_dem.h */ jeolib-miallib-1.1.6/core/c/miallib_dist.h000066400000000000000000000026301467232417700203670ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_DIST_H #define _MIALLIB_DIST_H 1 #include "mialtypes.h" /* dist.c */ extern ERROR_TYPE dst2d4(IMAGE *im); extern ERROR_TYPE dst2dchamfer(IMAGE *im); extern ERROR_TYPE chamfer2d(IMAGE *im, int type); extern IMAGE *edistfifo2d(IMAGE *im, int graph); /* efedt.c */ extern IMAGE *sqedt(IMAGE *im); extern IMAGE *iz(IMAGE *im); /* oiiz.c */ extern ERROR_TYPE oiiz(IMAGE *im); /* geodist.c */ extern ERROR_TYPE geodist(IMAGE *im_m, IMAGE *im_r, int graph); /* ced.c */ extern IMAGE *ced(IMAGE *ref, IMAGE *mask); #endif /* miallib_dist.h */ jeolib-miallib-1.1.6/core/c/miallib_erodil.h000066400000000000000000000042671467232417700207120ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_ERODIL_H #define _MIALLIB_ERODIL_H 1 #include "mialtypes.h" /* lerodil.c */ extern ERROR_TYPE linero(IMAGE *im, int dx, int dy, int n, int line_type); extern ERROR_TYPE lindil(IMAGE *im, int dx, int dy, int n,int line_type); /* herk.c */ extern ERROR_TYPE herkpldil(IMAGE *im, int dx, int dy, int k, int o, int t); extern ERROR_TYPE herkplero(IMAGE *im, int dx, int dy, int k, int o, int t); /* erodil.c */ extern ERROR_TYPE erode4(IMAGE *im, int ox, int oy); extern ERROR_TYPE dilate4(IMAGE *im, int ox, int oy); extern IMAGE *erode(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag); extern IMAGE *dilate(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int trflag); extern IMAGE *volerode(IMAGE *im, IMAGE *imse, IMAGE *imweight, int ox, int oy, int oz); extern IMAGE *rank(IMAGE *im, IMAGE *imse, int rank, int ox, int oy, int oz, int trflag); /* rank.c */ extern IMAGE *squarerank(IMAGE *im, int k, int rank, int ox, int oy); /* linerank.c */ extern ERROR_TYPE linerank(IMAGE *im, int dx, int dy, int k, int rank, int o); /* herkbl.c */ extern IMAGE *lrankti(IMAGE *im, int dx, int dy, int k, int rank, int o, int t, int tr); /* msmm.c */ extern IMAGE *msgradlinf(IMAGE **imap, int nc, int graph); extern IMAGE *msgradlinfngb(IMAGE **imap, int nc, IMAGE *imngb, int ox, int oy, int oz); #endif /* miallib_erodil.h */ jeolib-miallib-1.1.6/core/c/miallib_format.h000066400000000000000000000032561467232417700207210ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_FORMAT_H #define _MIALLIB_FORMAT_H 1 #include "mialtypes.h" /* format.c */ extern IMAGE *to_tiff1bitpp(IMAGE *im); extern IMAGE *to_tiff4bitpp(IMAGE *im); extern IMAGE *to_ushort(IMAGE *im); extern IMAGE *to_int32(IMAGE *im); extern IMAGE *to_float(IMAGE *im); extern IMAGE *to_double(IMAGE *im); extern ERROR_TYPE to_uchar(IMAGE *im); extern ERROR_TYPE dbltofloat(IMAGE *im); extern ERROR_TYPE uint32_to_float(IMAGE *im); extern ERROR_TYPE swap(IMAGE *im); /* miscel.c */ extern IMAGE *deinterleave(IMAGE *im); /* colconv.c */ extern IMAGE *imhsi2rgb(IMAGE *imh, IMAGE *ims, IMAGE *imi); extern IMAGE *imhls2rgb(IMAGE *imh, IMAGE *ims, IMAGE *imi); extern IMAGE **imrgb2hsx(IMAGE *imr, IMAGE *img, IMAGE *imb, int type); extern IMAGE *crgb2rgb(IMAGE *imh, IMAGE *ims, IMAGE *imi); #endif /* miallib_format.h */ jeolib-miallib-1.1.6/core/c/miallib_geodesy.h000066400000000000000000000030521467232417700210620ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_GEODESY_H #define _MIALLIB_GEODESY_H 1 #include "mialtypes.h" /* recons.c */ extern ERROR_TYPE rdil(IMAGE *mark, IMAGE *mask, int graph, int flag); extern ERROR_TYPE rero(IMAGE *mark, IMAGE *mask, int graph, int flag); extern ERROR_TYPE rerodilp(IMAGE *mark, IMAGE *mask, int graph, int flag, int version); /* complete.c */ extern ERROR_TYPE complete(IMAGE *im_i, IMAGE *im_rmin, int graph); /* rminmax.c */ extern IMAGE *minima(IMAGE *imin, int graph); /* ggeo.c */ extern ERROR_TYPE sqtgpla(IMAGE *im_m, IMAGE *im_r, int graph); extern ERROR_TYPE sqtg(IMAGE *im_m, IMAGE *im_r, int graph); extern IMAGE *sqtgsym(IMAGE *im_m, IMAGE *im_r, int graph); #endif /* miallib_geodesy.h */ jeolib-miallib-1.1.6/core/c/miallib_geometry.h000066400000000000000000000035451467232417700212650ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_GEOMETRY_H #define _MIALLIB_GEOMETRY_H 1 #include "mialtypes.h" /* geom.c */ extern ERROR_TYPE framebox(IMAGE *im, int *box, G_TYPE gval); extern ERROR_TYPE addframebox(IMAGE *im, int *box, G_TYPE gval); extern ERROR_TYPE subframebox(IMAGE *im, int *box); extern ERROR_TYPE imputop(IMAGE *im1, IMAGE *im2, int x, int y, int z, int op); extern ERROR_TYPE imputcompose(IMAGE *im1, IMAGE *imlbl, IMAGE *im2, int x, int y, int z, int val); extern IMAGE *imcut(IMAGE *im, int x1, int y1, int z1, int x2, int y2, int z2); extern IMAGE *getboundingbox(IMAGE *im); extern IMAGE *magnify(IMAGE *im, int n); extern IMAGE **rotatecoor(IMAGE *im, double theta); /* setshft.c */ extern ERROR_TYPE szcompat(IMAGE *im1, IMAGE *im2); extern ERROR_TYPE szgeocompat(IMAGE *im1, IMAGE *im2); /* bresenham.c */ extern ERROR_TYPE plotline(IMAGE *im, int x1, int y1, int x2, int y2, int val); /* ovlmatrix.c */ extern ERROR_TYPE ovlmatrix(IMAGE *matrix, IMAGE *maxg_array, char *odir); #endif /* miallib_geometry.h */ jeolib-miallib-1.1.6/core/c/miallib_hmt.h000066400000000000000000000034011467232417700202110ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_HMT_H #define _MIALLIB_HMT_H 1 #include "mialtypes.h" /* skelodthin.c */ extern ERROR_TYPE skeleton(IMAGE *im); extern ERROR_TYPE bprune(IMAGE *im, int occa, int graph); /* epc.c */ extern IMAGE *epc(IMAGE *im, IMAGE *lut); extern IMAGE *epcgrey(IMAGE *im, IMAGE *lut); /* switch.c */ extern IMAGE *switchop(IMAGE *im, IMAGE *imse, int ox, int oy, int oz); /* oiht.c */ extern ERROR_TYPE oiskeleton(IMAGE *im, IMAGE *imanchor); extern ERROR_TYPE oiask(IMAGE *im, IMAGE *imanchor); #ifdef ODOITHIN /* skel.c */ extern ERROR_TYPE binODthin_noqueue(IMAGE *imin, int stype, int atype, IMAGE *imanchor); extern ERROR_TYPE binODthin_FIFO(IMAGE *imin, int stype, int atype, IMAGE *imanchor); extern ERROR_TYPE binOIthin_noqueue(IMAGE *imin, int stype, int atype, IMAGE *imanchor); extern ERROR_TYPE binOIthin_FIFO(IMAGE *imin, int stype, int atype, IMAGE *imanchor); #endif #endif /* miallib_hmt.h */ jeolib-miallib-1.1.6/core/c/miallib_imem.h000066400000000000000000000037171467232417700203620ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_IMEM_H #define _MIALLIB_IMEM_H 1 #include "mialtypes.h" /* imem.c */ // extern void free_image(IMAGE *im); extern ERROR_TYPE iminfo(IMAGE *im); extern IMAGE *create_image(int data_type, long int nx, int ny, int nz); extern IMAGE *copy_image(IMAGE *im); extern ERROR_TYPE copy_lut(IMAGE *im1, IMAGE *im2); extern ERROR_TYPE create_lut(IMAGE *im); extern void free_lut(IMAGE *im); extern IMAGE *imtoarray(IMAGE *im, IMAGE *imroi); extern IMAGE *arraytoim(IMAGE *im, IMAGE *imroi); extern ERROR_TYPE FindPixWithVal(IMAGE *im, G_TYPE gval, unsigned long int *ofs); extern ERROR_TYPE dumpxyz(IMAGE *im, int x, int y, int z, int dx, int dy); /* note: not wrapped in mialisp */ extern ERROR_TYPE setpixval(IMAGE *im, unsigned long offset, G_TYPE g); extern G_TYPE getpixval(IMAGE *im, unsigned long offset); extern int GetImBitPerPixel(IMAGE *im); // extern IMAGE **create_imarray(int); /* shm.c */ // extern IMAGE *shmatimage(key_t shmkey, size_t nx, size_t ny, size_t nz, size_t nbyte, int type); // extern ERROR_TYPE shmdtimage(void *shm_address, int semkey_flag, key_t semkey); #endif /* miallib_imem.h */ jeolib-miallib-1.1.6/core/c/miallib_io.h000066400000000000000000000052061467232417700200350ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_IO_H #define _MIALLIB_IO_H 1 #include "mialtypes.h" /* imio_gdal.c */ extern int GDAL2MIALDataType(int aGDALDataType); extern IMAGE *GDALInfoJIP(char *imfn); extern IMAGE *GDALRead(char *imfn, int band, int nXOff, int nYOff, int nXSize, int nYSize, int nBufXSize, int nBufYSize); /* imio.c */ extern IMAGE *read_all(char *fn, int nx, int ny, int nz, int data_type, int header_size, int pc); extern IMAGE *read_image(char *fn); extern IMAGE *read_image_to_type(char *fn, int data_type); // extern ERROR_TYPE read_image_data(FILE *fp, IMAGE *im, int pc); // extern ERROR_TYPE write_image_data(FILE *fp, IMAGE *im, int pc); extern ERROR_TYPE write_ColorMap_tiff(IMAGE *im, char *fn); extern ERROR_TYPE write_tiff(IMAGE *im, char *fn); extern ERROR_TYPE writeTiffOneStripPerLine(IMAGE *im, char *fn, char *desc); /* imio2.c */ extern IMAGE *GetGeoKey(char *fname, char *keyname); extern IMAGE *GetTIFFTagGeo(char *fn, char *tagname); extern IMAGE *read_image2(char *fn, int x, int y, int szx, int szy, int scale); extern IMAGE *readTiffSubset(char *fn, int x, int y, unsigned szx, unsigned szy); extern ERROR_TYPE tiffinfo(char *fn, char *field, float *val); extern IMAGE *tiffinfoJIP(char *fn); // extern ERROR_TYPE read_image_data2(FILE *fp, IMAGE *im, int x, int y, int inx, int scale); extern ERROR_TYPE writeGeoTiffOneStripPerLine(IMAGE *im, char *fn, int PCSCode, double xoff, double yoff, double scale, unsigned short RasterType, int nodata_flag, int nodata_val, int metadata_flag, char *metadata_str); extern ERROR_TYPE writeMBGeoTiffOneStripPerLine(IMAGE **imap, int nc, char *fn, int PCSCode, double xoff, double yoff, double scale, unsigned short RasterType, int nodata_flag, int nodata_val, int metadata_flag, char *metadata_str); extern void print_mia_banner(); #endif /* miallib_io.h */ jeolib-miallib-1.1.6/core/c/miallib_label.h000066400000000000000000000107271467232417700205110ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_LABEL_H #define _MIALLIB_LABEL_H 1 #include "mialtypes.h" /* label.c */ extern ERROR_TYPE label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz); extern ERROR_TYPE labelpixngb(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz); extern ERROR_TYPE labelplat(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz); extern ERROR_TYPE seededlabelplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz); extern ERROR_TYPE seededplat(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz); extern ERROR_TYPE labelpix(IMAGE *im); extern ERROR_TYPE resolveLabels(IMAGE *imlbl, IMAGE *imlut, IMAGE *imlutback, int graph); extern ERROR_TYPE gorder(IMAGE *lbl, IMAGE *g, int n); /* mmlabel.c */ extern IMAGE *erodelabel(IMAGE *im, int graph); /* propagate.c */ extern ERROR_TYPE propagate(IMAGE *lbl, IMAGE *dst, IMAGE **imap, int nc, int graph); /* setreg.c */ extern ERROR_TYPE set_regions(IMAGE *ilbl, IMAGE *ival, int indic); extern ERROR_TYPE setregionsgraph(IMAGE *ilbl, IMAGE *ival, int indic, int graph); extern ERROR_TYPE tessel_surface(IMAGE *im); extern ERROR_TYPE relabel(IMAGE *ilbl1, IMAGE *ilbl2, IMAGE *iarea2); /* setreglut.c */ extern IMAGE *region_lut(IMAGE *ilbl, int graph, int type, int param1, int param2); extern IMAGE *region_lut_seq(IMAGE *ilbl, int graph, int type); extern IMAGE *region_im_lut(IMAGE *ilbl, IMAGE *im, int graph, int type, float aval); extern IMAGE *contortion_lut(IMAGE *ilbl, int graph); extern IMAGE *moments_lut_to_ellipse_lut(IMAGE **impq); /* alphacc.c */ extern IMAGE *alphacc(IMAGE *dissx, IMAGE *dissy, int alpha); /* labelvertex.c */ extern IMAGE *labelvertex(IMAGE *im, int alpha, int graph); extern IMAGE *vertexseparation(IMAGE *im, int graph, int type); extern IMAGE *labelvertexconnectedness(IMAGE *im, int alpha, int graph, int deg); /* labelccfastrim.c */ extern IMAGE *labelcc(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rg, int rl); /* labelccms.c */ extern IMAGE *labelccms(IMAGE **imap, int nc, IMAGE *imse, int ox, int oy, int oz, int r1, int r2); /* labelccmi.c */ extern IMAGE *labelccmi(IMAGE *im, IMAGE *immi, IMAGE *imse, int ox, int oy, int oz, int rg, int rl); /* labelci.c */ extern IMAGE *labelci(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rl); /* labelcims.c: */ extern IMAGE *labelcims(IMAGE **imap, int nc, IMAGE *imse, int ox, int oy, int oz, int rl); /* labelccdissim.c */ extern IMAGE *labelccdissim(IMAGE *im, IMAGE *imh, IMAGE *imv, int rg, int rl); /* labelccvar.c */ extern IMAGE *labelccvar(IMAGE *im, IMAGE *imse, int ox, int oy, int oz, int rg, int rl, double varmax); /* labelccmsdissim.c: */ extern IMAGE *labelccmsdissim(IMAGE **imap, int nc, IMAGE *imh, IMAGE *imv, int rg, int rl); /* newlabelcc.c */ extern IMAGE *labelccattr(IMAGE *im, int graph, int rg, int rl); /* alphatree.c */ extern IMAGE **alphatree(IMAGE *dissx, IMAGE *dissy, int alphamax); extern IMAGE *alphatreeincattr(IMAGE **atree, IMAGE **attr0cc, int type); extern IMAGE *alphatreetoCCs(IMAGE **atree, IMAGE *imblbl, IMAGE *flaglut, int rule); extern IMAGE *alphatreenextlevel(IMAGE **atree, IMAGE *crtprtlabel, int alpha); extern IMAGE *alphatreepersistencelut(IMAGE **atree); /* alphatreetoCCs.c */ /* none exposed, used internally in alphatree.c */ /* edgeweight.c */ extern IMAGE *edgeweight(IMAGE *im, int dir, int type); /* dbscan.c */ extern IMAGE *dissim(IMAGE **imap, int nc, IMAGE *mask, int type); extern IMAGE *dbscan(IMAGE *dissim, double eps, int MinPts); /* outeredge.c */ extern IMAGE *outeredgelut(IMAGE *ilbl, IMAGE *iedgelbl); extern IMAGE *outeredge(IMAGE *ilbl, int graph); extern IMAGE *outercontour(IMAGE *ilbl, int graph); #endif /* miallib_label.h */ jeolib-miallib-1.1.6/core/c/miallib_miscel.h000066400000000000000000000026541467232417700207060ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_MISCEL_H #define _MIALLIB_MISCEL_H 1 #include "mialtypes.h" /* dirmean.c */ extern IMAGE *dirmean(IMAGE *imx, IMAGE *imy, IMAGE *imse, int ox, int oy, int oz); extern IMAGE *coherence(IMAGE *imx, IMAGE *imy, IMAGE *imse, int ox, int oy, int oz); /* gsl.c */ extern IMAGE *coor_extrema_paraboloid(IMAGE *b); extern IMAGE *fitlinear(IMAGE *xarray, IMAGE *yarray); /* transition.c */ extern IMAGE *transgrad(IMAGE *im, int graph); /* remsens.c */ extern double julian_date(short int year, short int month, short int day, double hour); #endif /* miallib_miscel.h */ jeolib-miallib-1.1.6/core/c/miallib_opclo.h000066400000000000000000000030571467232417700205440ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_OPCLO_H #define _MIALLIB_OPCLO_H 1 #include "mialtypes.h" /* uswilk.c */ extern IMAGE *attribute(IMAGE *imliiar, int type, int oporclo, double lambdaVal, int graph); extern IMAGE *GreyAreaOpening(IMAGE *imliiar, int lambdaVal, int graph); extern IMAGE *GreyAreaClosing(IMAGE *imliiar, int lambdaVal, int graph); extern IMAGE *GreyAreaOpeningROI(IMAGE *imliiar, int lambdaVal, int graph); extern IMAGE *GreyAreaClosingROI(IMAGE *imliiar, int lambdaVal, int graph); /* myhull.c */ // extern IMAGE *chull(IMAGE *ilbl, int graph); /* hull.c */ extern IMAGE *hpclose(IMAGE *im, int dx, int dy); /* hullti.c */ extern IMAGE *hpcloseti(IMAGE *im, int dx, int dy); #endif /* miallib_opclo.h */ jeolib-miallib-1.1.6/core/c/miallib_pointop.h000066400000000000000000000037151467232417700211210ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_POINTOP_H #define _MIALLIB_POINTOP_H 1 #include "mialtypes.h" /* pointop.c */ extern ERROR_TYPE bitwise_op(IMAGE *im1, IMAGE *im2, int op); extern ERROR_TYPE negation(IMAGE *im); extern ERROR_TYPE arith(IMAGE *im1, IMAGE *im2, int op); extern ERROR_TYPE arithcst(IMAGE *im, G_TYPE gt, int op); extern ERROR_TYPE imabs(IMAGE *im); extern ERROR_TYPE imsqrt(IMAGE *im); extern ERROR_TYPE imlog(IMAGE *im); extern ERROR_TYPE imatan(IMAGE *im); extern ERROR_TYPE imcos(IMAGE *im); extern ERROR_TYPE imacos(IMAGE *im); extern ERROR_TYPE imsin(IMAGE *im); extern ERROR_TYPE imasin(IMAGE *im); extern ERROR_TYPE thresh(IMAGE *im, G_TYPE gt1, G_TYPE gt2, G_TYPE gbg, G_TYPE gfg); extern ERROR_TYPE setlevel(IMAGE *im, G_TYPE gt1, G_TYPE gt2, G_TYPE gval); extern ERROR_TYPE modulo(IMAGE *im, int val); extern ERROR_TYPE complement(IMAGE *im); extern ERROR_TYPE power2p(IMAGE *im); extern ERROR_TYPE blank(IMAGE *im, G_TYPE gval); extern ERROR_TYPE shift(IMAGE *im, int val); extern ERROR_TYPE setrange(IMAGE *im, G_TYPE gt1, G_TYPE gt2); extern IMAGE *ndi(IMAGE *im1, IMAGE *im2); #endif /* miallib_pointop.h */ jeolib-miallib-1.1.6/core/c/miallib_proj.h000066400000000000000000000023011467232417700203710ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_PROJ_H #define _MIALLIB_PROJ_H 1 #include "mialtypes.h" /* grid.c */ extern IMAGE *grid(IMAGE *im, IMAGE *roi, IMAGE *imx, IMAGE *imy, float alpha); /* projection.c */ extern IMAGE **cs2cs(double ulc_e, double ulc_n, int nx, int ny, double res, char *parmsi[], int ni, char *parmso[], int no); #endif /* miallib_proj.h */ jeolib-miallib-1.1.6/core/c/miallib_segment.h000066400000000000000000000063051467232417700210710ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_SEGMENT_H #define _MIALLIB_SEGMENT_H 1 #include "mialtypes.h" /* wshed.c */ extern IMAGE *ws(IMAGE *im, int graph); /* wsfah.c */ extern ERROR_TYPE wsfah(IMAGE *iml, IMAGE *imr, int graph, int maxfl); extern ERROR_TYPE skelfah(IMAGE *iml, IMAGE *imr, IMAGE *imdir, int graph, int maxfl); extern ERROR_TYPE skelfah2(IMAGE *imc, IMAGE *impskp, int n, int graph); extern ERROR_TYPE compose(IMAGE *mark, IMAGE *mask, IMAGE *g, IMAGE *lbl, int graph); /* oiws.c */ extern ERROR_TYPE oiws(IMAGE *im); /* srg.c */ extern ERROR_TYPE srg(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz); extern ERROR_TYPE mssrg(IMAGE **imap, int nc, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz); extern ERROR_TYPE mssrgcore(IMAGE **imap, int nc, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz); /************************************************************************************/ #ifdef MCISRG /* mslabel.c */ extern IMAGE *labelImage(IMAGE **imap, int nc, IMAGE *labelIm, int graph, long int lambda); /* determineSize.c */ extern long int thresholdRegion_Size(IMAGE *inputIm, unsigned long int threshold); extern long int thresholdRegion_Contrast(IMAGE **imap, int nc, IMAGE *inputIm, unsigned long int threshold); /* mcisrg.c */ extern ERROR_TYPE mcisrg(IMAGE **imap, int nc, IMAGE *seedsIm, int graph, long int regionNumber, int version); /* segmentation.c */ extern IMAGE *segmentImage(IMAGE **imap, int nc, int graph, int varianz, long int regionSize, int contrast, int version, char *fndat); extern ERROR_TYPE writeGnuPlot3D(IMAGE **imap, int nc, int graph, int regionSize, int varianz, char *fileName); /* vectorize.c */ extern ERROR_TYPE vectorizeImage(IMAGE **imap, int nc, char *filename, int format, double simplifyBorderLines); #endif /************************************************************************************/ /* partorp.c */ extern ERROR_TYPE IsPartitionEqual(IMAGE *im1, IMAGE *im2, int *result); extern ERROR_TYPE IsPartitionFiner(IMAGE *im1, IMAGE *im2, int graph, unsigned long int *res); /* dendro.c */ extern IMAGE **imgc(IMAGE *imlbl); extern ERROR_TYPE dendro(IMAGE **imap, int nc, char *fn); /* partition.c */ extern IMAGE **PartitionSimilarity(IMAGE *part1, IMAGE *part2, int graph); /* mspa.c */ extern IMAGE *segmentBinaryPatterns(IMAGE *imin, float size, int graphfg, int transition, int internal); #endif /* miallib_segment.h */ jeolib-miallib-1.1.6/core/c/miallib_stats.h000066400000000000000000000057561467232417700205760ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIALLIB_STATS_H #define _MIALLIB_STATS_H 1 #include "mialtypes.h" /* imstat.c */ extern IMAGE *histo1d(IMAGE *im); extern IMAGE *histo2d(IMAGE *im1, IMAGE *im2); extern IMAGE *histo3d(IMAGE *im1, IMAGE *im2, IMAGE *im3); extern IMAGE *rsum(IMAGE *im); extern IMAGE *lookuprgb(IMAGE *imr, IMAGE *img, IMAGE *imb, IMAGE *imlut); extern IMAGE *class2d(IMAGE *im1, IMAGE *im2, IMAGE *imlut); extern IMAGE *area(IMAGE *im, int r, int type); extern IMAGE *dirsum(IMAGE *im, int dir); extern G_TYPE *min_max(IMAGE *im); extern ERROR_TYPE getfirstmaxpos(IMAGE *im, unsigned long int *pos); extern ERROR_TYPE histcompress(IMAGE *im); extern ERROR_TYPE lookup(IMAGE *im, IMAGE *imlut); extern ERROR_TYPE lookuptypematch(IMAGE *im, IMAGE *imlut); extern ERROR_TYPE volume(IMAGE *im); extern ERROR_TYPE dirmax(IMAGE *im, int dir); extern ERROR_TYPE imequalp(IMAGE *im1, IMAGE *im2); extern ERROR_TYPE getmax(IMAGE *im, double *maxval); extern ERROR_TYPE getminmax(IMAGE *im, double *minval, double *maxval); /* histo.c */ extern IMAGE **histrgbmatch(IMAGE *cdf_rgb_src, IMAGE *cdf_rg_tgt, IMAGE *cdf_rb_tgt, IMAGE *cdf_gb_tgt); extern IMAGE **histrgb3dmatch(IMAGE *cdf_rgb_src, IMAGE *cdf_rg_tgt, IMAGE *cdf_rb_tgt, IMAGE *cdf_gb_tgt); /* mblincomb.c */ extern ERROR_TYPE mblincomb(IMAGE **imap, int nc, IMAGE *matrix); extern ERROR_TYPE condmean(IMAGE **imap, int nc); /* indexx.c */ extern IMAGE *sortindex(IMAGE *i0); #ifdef CLASSIF /* classification.c */ extern ERROR_TYPE classstatsinfo(IMAGE *immos, IMAGE *imin); extern ERROR_TYPE clmindist(IMAGE *immos, IMAGE *imin, int bklabel, int mode, double thr); extern ERROR_TYPE clparpip(IMAGE *immos, IMAGE *imin, int bklabel, int mode, double mult); extern ERROR_TYPE clmaha(IMAGE *immos, IMAGE *imin, int bklabel, int mode, double thr); extern ERROR_TYPE clmaxlike(IMAGE *immos, IMAGE *imin, int bklabel, int type, double thr); #endif /* registration.c */ extern IMAGE *ssda(IMAGE *imin, IMAGE *imt, int xi, int yi, int w); extern IMAGE *ncclewis(IMAGE *imin, IMAGE *imt, IMAGE *sim, IMAGE *ssqim, int xi, int yi, int w); extern IMAGE *ncc(IMAGE *imin, IMAGE *imt, int xi, int yi, int w); #endif /* miallib_stats.h */ jeolib-miallib-1.1.6/core/c/miallib_swig.h000066400000000000000000000202521467232417700203750ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* ** Header file for image analysis routines ** by Pierre Soille@ec.europa.eu 1988--2016 */ #ifndef _MIAL_GLUE_H_ #define _MIAL_GLUE_H_ #ifdef PYTHON #include #define printf PySys_WriteStdout #endif #ifndef INT_LIIAR #define INT_LIIAR #include "mialtypes.h" /* */ #define ERROR 1 #define NO_ERROR 0 #define TRUE 1 #define FALSE 0 #ifndef PI #define PI 3.14159265358979323846 /* same as in XLISP-PLUS */ #endif /* adjust to local system */ #define BITPERCHAR 8 #define BITPERSHORT 16 #define BITPERINT32 32 #define BITPERINT64 64 #define BITPERFLOAT 32 #define BITPERDOUBLE 64 #define BITPERWORD (sizeof(long int)*8) #define BYTEPERWORD sizeof(long int) #define BITPERBAND 8 #if (__WORDSIZE==32) #define W_MSB 0x80000000 #elif (__WORDSIZE==64) #define W_MSB 0x8000000000000000 #endif #ifndef UCHAR_MIN #define UCHAR_MIN 0 #endif #ifndef UCHAR_MAX #define UCHAR_MAX 0xFF #endif #ifndef SHORT_MIN #define SHORT_MIN -0x8000 #endif #ifndef SHORT_MAX #define SHORT_MAX 0x7FFF #endif #ifndef INT_MIN #define INT_MIN -0x80000000 #endif #ifndef INT_MAX #define INT_MAX 0x7FFFFFFF #endif #ifndef USHORT_MIN #define USHORT_MIN 0 #endif #ifndef USHORT_MAX #define USHORT_MAX 0xFFFF #endif #ifndef INT32_MIN #define INT32_MIN -0x80000000 #endif #ifndef INT32_MAX #define INT32_MAX 0x7FFFFFFF #endif #ifndef UINT32_MIN #define UINT32_MIN 0 #endif #ifndef UINT32_MAX #define UINT32_MAX 0xFFFFFFFF #endif #ifndef INT64_MIN #define INT64_MIN -0x8000000000000000 #endif #ifndef INT64_MAX #define INT64_MAX 0x7FFFFFFFFFFFFFFF #endif #ifndef UINT64_MIN #define UINT64_MIN 0 #endif #ifndef UINT64_MAX #define UINT64_MAX 0xFFFFFFFFFFFFFFFF #endif #define MIALFLOAT_MAX ((float)3.40282346638528860e+38) #define MIALFLOAT_MIN ((float)1.40129846432481707e-45) #ifndef DOUBLE_MAX #define DOUBLE_MAX 1.797693134862315708e+308 #endif #ifndef DOUBLE_MIN #define DOUBLE_MIN 4.94065645841246544e-324 #endif /* pixel type table */ #define t_TIFFONEBITPERPIXEL 12 #define t_ONEBITPERPIXEL 0 #define t_FOURBITPERPIXEL 1 #define t_CHAR 2 /* all should be in the form e.g. uc_TYPE */ #define t_UCHAR 3 #define t_SHORT 4 #define t_USHORT 5 #define t_INT32 6 #define t_UINT32 7 #define t_INT64 8 #define t_UINT64 9 #define t_FLOAT 10 #define t_MIALFLOAT 10 #define t_DOUBLE 11 #define t_RGB 13 /* fake type, requires pixel data type=t_UCHAR */ #define t_PTR 14 #define t_UNSUPPORTED 255 #define t_LBL_TYPE 6 /* consider unsigned long int in the future*/ #define LBL_MAX INT32_MAX #define t_GENERIC 3 #define t_HST1D 6 #define t_HST2D 3 /* different types should be allowed, 3 for ACCA */ #define t_HST3D 6 #define t_LUT 10 #define t_LABEL 6 /* macro definitions for grilisp (getset.h) */ #define GetImDataType(x) ((x)->DataType) /* data type of a pixel */ #define GetImPtr(x) ((x)->p_im) /* pointer to the first pixel */ #define GetImNx(x) ((unsigned long int)(x)->nx) #define GetImNy(x) ((unsigned long int)(x)->ny) #define GetImNz(x) ((unsigned long int)(x)->nz) #define GetImNlin(x) ((unsigned long int)(x)->nz * (x)->ny) #define GetImNPix(x) ((unsigned long int)(x)->nx * (x)->ny * (x)->nz) #define GetImNPixPerPlane(x) (((unsigned long int)(x)->nx) * (x)->ny) #define GetImNByte(x) ((unsigned long int)(x)->NByte) #define GetImCenter(x) ((x)->center) #define GetImVol(x) ((x)->vol) /* must call volume() before */ #define GetImLut(x) ((x)->lut) #define GetImMin(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (val) = (x)->umin.uc_val; \ break; \ case t_USHORT: \ (val) = (x)->umin.us_val; \ break; \ case t_SHORT: \ (val) = (x)->umin.s_val; \ break; \ case t_INT32: \ (val) = (x)->umin.i32_val; \ break; \ case t_UINT32: \ (val) = (x)->umin.u32_val; \ break; \ case t_INT64: \ (val) = (x)->umin.i64_val; \ break; \ case t_UINT64: \ (val) = (x)->umin.u64_val; \ break; \ case t_FLOAT: \ (val) = (x)->umin.f_val; \ break; \ case t_DOUBLE: \ (val)= (x)->umin.d_val; \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in GetImMin \ macro\n"); \ } #define GetImMax(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (val) = (x)->umax.uc_val; \ break; \ case t_USHORT: \ (val) = (x)->umax.us_val; \ break; \ case t_SHORT: \ (val) = (x)->umax.s_val; \ break; \ case t_INT32: \ (val) = (x)->umax.i32_val; \ break; \ case t_UINT32: \ (val) = (x)->umax.u32_val; \ break; \ case t_INT64: \ (val) = (x)->umax.i64_val; \ break; \ case t_UINT64: \ (val) = (x)->umax.u64_val; \ break; \ case t_FLOAT: \ (val) = (x)->umax.f_val; \ break; \ case t_DOUBLE: \ (val)= (x)->umax.d_val; \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in GetImMax \ macro\n"); \ } #define SetImDataType(x, val) ((x)->DataType = (val)) #define SetImPtr(x, val) ((x)->p_im = (void *)(val)) #define SetImNByte(x, val) ((x)->NByte = (val)) #define SetImNx(x, val) ((x)->nx = (val)) #define SetImNy(x, val) ((x)->ny = (val)) #define SetImNz(x, val) ((x)->nz = (val)) #define SetImCenter(x, val) ((x)->center = (val)) #define SetImVol(x,val) ((x)->vol = (VOL_TYPE)(val)) #define SetImLut(x, val) ((x)->lut = (val)) #define SetImMin(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (x)->umin.uc_val = (UCHAR)(val); \ break; \ case t_USHORT: \ (x)->umin.us_val = (USHORT)(val); \ break; \ case t_SHORT: \ (x)->umin.s_val = (SHORT)(val); \ break; \ case t_INT32: \ (x)->umin.i32_val = (INT32)(val); \ break; \ case t_UINT32: \ (x)->umin.u32_val = (UINT32)(val); \ break; \ case t_INT64: \ (x)->umin.i64_val = (INT64)(val); \ break; \ case t_UINT32: \ (x)->umin.u64_val = (UINT64)(val); \ break; \ case t_FLOAT: \ (x)->umin.f_val = (float)(val); \ break; \ case t_DOUBLE: \ (x)->umin.d_val = (double)(val); \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in SetImMin \ macro\n"); \ } #define SetImMax(x, val) \ switch(GetImDataType(x)){ \ case t_UCHAR: \ (x)->umax.uc_val = (UCHAR)(val); \ break; \ case t_USHORT: \ (x)->umax.us_val = (USHORT)(val); \ break; \ case t_SHORT: \ (x)->umax.s_val = (SHORT)(val); \ break; \ case t_INT32: \ (x)->umax.i32_val = (INT32)(val); \ break; \ case t_UINT32: \ (x)->umax.u32_val = (UINT32)(val); \ break; \ case t_INT64: \ (x)->umax.i64_val = (INT64)(val); \ break; \ case t_UINT64: \ (x)->umax.u64_val = (UINT64)(val); \ break; \ case t_FLOAT: \ (x)->umax.f_val = (float)(val); \ break; \ case t_DOUBLE: \ (x)->umax.d_val = (double)(val); \ break; \ default: \ (void)fprintf(stderr,"WARNING: \ invalid data type in SetImMax \ macro\n"); \ } /* external function declarations */ #endif /* #ifndef INT_LIIAR */ #endif jeolib-miallib-1.1.6/core/c/mialtypes.h000066400000000000000000000065551467232417700177540ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifndef _MIATYPES_H #define _MIATYPES_H 1 /* type definitions */ /* consider using or referring to stdint.h in the future*/ typedef unsigned long int mia_size_t; typedef unsigned char DST_TYPE; typedef unsigned char GENERICPIX; typedef unsigned char RGB_TYPE; typedef int HST1D_TYPE; typedef unsigned char HST2D_TYPE; typedef int HST3D_TYPE; typedef float LUT_TYPE; typedef char CHAR; typedef unsigned char UCHAR; typedef int INT; typedef int INT32; typedef unsigned int UINT32; typedef long long int INT64; typedef unsigned long long int UINT64; typedef short int SHORT; typedef unsigned short int USHORT; typedef float MIALFLOAT; /* FLOAT defined as double in windows ... */ typedef double DOUBLE; typedef void * NULL_TYPE; typedef int ERROR_TYPE; typedef double VOL_TYPE; typedef void * PTR_TYPE; typedef int LBL_TYPE; /* should be unsigned, see also t_LBL_TYPE */ /* consider defining long long type (8 bytes) on 486: int64 */ typedef struct { GENERICPIX generic_val; UCHAR uc_val; USHORT us_val; SHORT s_val; UINT32 u32_val; INT32 i32_val; UINT64 u64_val; INT64 i64_val; MIALFLOAT f_val; DOUBLE d_val; } G_TYPE; /* consider projectioncode ulx uly ulz resx resy resz */ typedef struct { void *p_im; /* Pointer to image data */ int DataType; /* Image data type */ int nx; /* Number of columns */ int ny; /* Number of lines */ int nz; /* Number of x-y planes */ mia_size_t NByte; /* Number of bytes for image data */ VOL_TYPE vol; /* Sum of pixel values (volume) */ USHORT *lut; /* Pointer to colour map */ G_TYPE g; /* used to store a value matching DataType (see e.g. alphacc.c) */ } IMAGE; typedef struct { /* structure for blob analysis */ int area; /* number of pixels */ int m00; /* moments of order p-q */ int m10; int m01; int minor; /* length of minor axis */ int major; /* length of major axis */ int irradiance; /* mean value * 255 */ double xcg; /* x coordinate of gravity centre */ double ycg; /* y coordinate of gravity centre */ double mu11; /* centred moments of order p-q */ double mu20; double mu02; double ratio; /* ratio between minor and major axis */ UCHAR dir; /* dir=360/(4pi) arctan(2mu11/(mu20-mu02)) */ double r; /* correlation coefficient */ } IMBLOB; #endif /* mialtypes.h */ jeolib-miallib-1.1.6/core/c/miscel.c000066400000000000000000000074571467232417700172160ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "miallib.h" #ifdef XLISP extern void xlabort(char *); /* serious XLISP error handler */ #endif void nrerror(char *error_text) { sprintf(buf,"Image library run-time error...\n"); errputstr(buf); sprintf(buf,"%s\n",error_text); errputstr(buf); sprintf(buf,"...now exiting to top-level...\n"); errputstr(buf); #ifdef XLISP xlabort("Emergency Emergency"); #else exit(1); #endif } /** \addtogroup group_format * @{ */ #include "uc_def.h" IMAGE *uc_deinterleave(IMAGE *im) { IMAGE *imout; PIX_TYPE *pin, *pout; unsigned long int nelem, x, j, nz=GetImNz(im); imout = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"deinterleave(im): not enough memory!\n"); errputstr(buf); return(NULL); } nelem=GetImNPixPerPlane(im); pin=(PIX_TYPE *)GetImPtr(im); pout=(PIX_TYPE *)GetImPtr(imout); for (x=0;x. ***********************************************************************/ #include #include #include #include "miallib.h" /** \addtogroup group_label * @{ */ #include "u32_def.h" IMAGE *u32_erodelabel(IMAGE *im1, int graph) { IMAGE *im2; PIX_TYPE *p1, *p1last, lblcrt; UCHAR *p2; int box[6]; long int shft[27], k; /* take graph into account */ if (set_seq_shift(GetImNx(im1), GetImNy(im1), GetImNz(im1), graph, shft) == ERROR){ return NULL; } /* create output image */ im2 = (IMAGE *)create_image(t_UCHAR, GetImNx(im1), GetImNy(im1), GetImNz(im1)); if (im2 == NULL){ (void)sprintf(buf,"ul_erodelabel(): not enough memory!\n"); errputstr(buf); return(im2); } if (GetImNy(im1) == 1) {BOX_1D;} else if (GetImNz(im1) == 1) {BOX_2D;} else {BOX_3D;} generic_blank(im2, 1); generic_framebox(im2, box, 0); p1=(PIX_TYPE *)GetImPtr(im1); p2=(UCHAR *)GetImPtr(im2); p1last=p1+GetImNPix(im1); for (; p1. ***********************************************************************/ /** * @file mslabel.c * @author Dominik Brunner and Pierre Soille * @date * * @details see also \cite brunner-soille2005 \cite brunner-soille2007 * */ /*************************************************************************** mslabel.c - description Extended version of fast breadth first stack algorithm (labeling algorithm) to find regions with same Pixel values following Pierre Soille. This version supports multispectral images! ------------------- begin : Tue Apr 13 2004 ***************************************************************************/ #include #include #include "mslabel.h" #include "miallib.h" #include "base.h" #include "fifo.h" /** \addtogroup group_label * @{ */ /* * labelImage: detects regions in a multispectral image. The generated * label image is stored in the attribute labelIm * * Parameters: * * imap array of pointer to the channels of an input images * (a given image MUST only appear once in the array) * * nc size of imap => number of channels * * labelIm pointer to an image in which the resulting label image is stored * * graph either 4 or 8 * * lambda lambda which is used to decide whether the pixel still belongs to * the region or not. A lambda of 0 means, that the pixel must have exactly the * same value in all channels than the region, in order to belong to it. * [Should be a vector of lambda values, one per channel] * * * * Return values: * * labelIm if everything is ok * * NULL if graph was not equal to 4 or 8 * if the dimensions of the input images and the label image are not equal */ #include "uc_def.h" IMAGE *uc_labelImage(IMAGE **imap, int nc, IMAGE *labelIm, int graph, long int lambda) { long int shft[27], offset, i, crtOffset, neighbourOffset; LBL_TYPE *pLabelIm, lval; PIX_TYPE *pInputIm; int nx, ny, k, abool, n; FIFO4 *hq; int box[6]; box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; // make checks on datatypes, and whether dimensions of images in // imap and labelIm fit together if (nc < 1){ return NULL; } for (i=1; i // easy handle of multichannel pictures offset = i; pLabelIm[offset]=++lval; // check the neighbours for (k = 0; k < graph; k++){ abool = 1; neighbourOffset = offset + shft[k]; // check whether neighbour has same value for all // channels if(pLabelIm[neighbourOffset] == NOTLABELED){ for (n = 0; n < nc; n++){ pInputIm = (PIX_TYPE *) GetImPtr(imap[n]); if ((( ((INT32) pInputIm[offset])-lambda) >pInputIm[neighbourOffset]) || \ (( ((INT32) pInputIm[offset])+lambda) put in queue if (abool){ fifo4_add(hq, (long int) (neighbourOffset)); pLabelIm[neighbourOffset] = lval; } } } while (fifo4_empty(hq) == 0){ crtOffset = (long int) fifo4_remove(hq); // check the neighbours for (k = 0; k < graph; k++){ // check whether Pixel has no label neighbourOffset = crtOffset + shft[k]; if (pLabelIm[neighbourOffset] == NOTLABELED){ abool = 1; // check whether neighbour has same value // for all channels for (n = 0; n < nc; n++){ pInputIm = (PIX_TYPE *) GetImPtr(imap[n]); /* srtOffset used here, was offset in previous version */ if ((( ((INT32) pInputIm[crtOffset])-lambda)>pInputIm[neighbourOffset]) || \ (( ((INT32) pInputIm[crtOffset])+lambda) put in queue if (abool){ fifo4_add(hq,(long int) (neighbourOffset)); pLabelIm[neighbourOffset] = lval; } } } } } } free_fifo4(hq); for(i=0; i // easy handle of multichannel pictures offset = i; pLabelIm[offset]=++lval; // check the neighbours for (k = 0; k < graph; k++){ abool = 1; neighbourOffset = offset + shft[k]; // check whether neighbour has same value for all // channels if(pLabelIm[neighbourOffset] == NOTLABELED){ for (n = 0; n < nc; n++){ pInputIm = (PIX_TYPE *) GetImPtr(imap[n]); if ((( ((INT32) pInputIm[offset])-lambda) >pInputIm[neighbourOffset]) || \ (( ((INT32) pInputIm[offset])+lambda) put in queue if (abool){ fifo4_add(hq, (long int) (neighbourOffset)); pLabelIm[neighbourOffset] = lval; } } } while (fifo4_empty(hq) == 0){ crtOffset = (long int) fifo4_remove(hq); // check the neighbours for (k = 0; k < graph; k++){ // check whether Pixel has no label neighbourOffset = crtOffset + shft[k]; if (pLabelIm[neighbourOffset] == NOTLABELED){ abool = 1; // check whether neighbour has same value // for all channels for (n = 0; n < nc; n++){ pInputIm = (PIX_TYPE *) GetImPtr(imap[n]); /* srtOffset used here, was offset in previous version */ if ((( ((INT32) pInputIm[crtOffset])-lambda)>pInputIm[neighbourOffset]) || \ (( ((INT32) pInputIm[crtOffset])+lambda) put in queue if (abool){ fifo4_add(hq,(long int) (neighbourOffset)); pLabelIm[neighbourOffset] = lval; } } } } } } free_fifo4(hq); for(i=0; i. ***********************************************************************/ /*************************************************************************** label.h - description ------------------- begin : Tue Apr 13 2004 ***************************************************************************/ #ifndef init_label #define init_label #include "miallib.h" extern IMAGE *labelImage(IMAGE **imap, int nc, IMAGE *labelIm, int graph, long int lambda); #endif jeolib-miallib-1.1.6/core/c/msmm.c000066400000000000000000000167171467232417700167120ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file msmm.c * @author Pierre SOILLE * @date Tue Oct 18 11:56:17 2016 [First 2004-04-20 snow down to sasso del ferro a Laveno yesterday!] * * @brief Multispectral gradient calculations * * */ #include #include #include #include #include "miallib.h" #include "uc_def.h" IMAGE *uc_msgradlinf(IMAGE **imap, int nc, int graph) { int i, k, b, ofs, ofsk, ofsmax; long int shft[27]; PIX_TYPE **pim; IMAGE *imout; MIALFLOAT *pout, dmax, dcrt, db; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); imout = create_image(t_FLOAT, GetImNx(imap[0]), GetImNy(imap[0]), GetImNz(imap[0])); if (imout == NULL){ (void)sprintf(buf,"uc_msgradlinf(): not enough memory for output image\n"); errputstr(buf); return(NULL); } pout=(MIALFLOAT *)GetImPtr(imout); for (i=0; idmax) dmax=dcrt; } *(pout+ofs)=(MIALFLOAT)sqrt((double)dmax); } return imout; } #include "uc_undef.h" #include "f_def.h" IMAGE *f_msgradlinf(IMAGE **imap, int nc, int graph) { int i, k, b, ofs, ofsk, ofsmax; long int shft[27]; PIX_TYPE **pim; IMAGE *imout; MIALFLOAT *pout, dmax, dcrt, db; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); imout = create_image(t_FLOAT, GetImNx(imap[0]), GetImNy(imap[0]), GetImNz(imap[0])); if (imout == NULL){ (void)sprintf(buf,"uc_msgradlinf(): not enough memory for output image\n"); errputstr(buf); return(NULL); } pout=(MIALFLOAT *)GetImPtr(imout); for (i=0; idmax) dmax=dcrt; } *(pout+ofs)=(MIALFLOAT)sqrt((double)dmax); } return imout; } #include "f_undef.h" /** * * * @param imap array of images * @param nc integer for number of images in array * @param graph integer for 2-D connectivity (either 4 or 8) * * @return graph-connected multispectral gradient of input multi-channel image (up to 255 channels) using definition of \cite soille96 */ IMAGE *msgradlinf(IMAGE **imap, int nc, int graph) { /* ** authors: Pierre Soille 28 Jan 2003 ** IMAGE **imap: array of images (multispectral image) ** int n: number of bands ** int graph: connectivity ** comment: */ switch (GetImDataType(imap[0])){ case t_UCHAR: return(uc_msgradlinf(imap, nc, graph)); break; case t_FLOAT: return(f_msgradlinf(imap, nc, graph)); break; default: (void)sprintf(buf,"msgradlinf(IMAGE **imap, int nc, int graph): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } #include "uc_def.h" #define t_OUT t_FLOAT #define PIX_OUT MIALFLOAT IMAGE *uc_msgradlinfngb(IMAGE **imap, int nc, IMAGE *imngb, int ox, int oy, int oz) { int i, k, n; int nx, ny, nz; long int x, y, z; long int lstx, lsty, lstz, ofs; long int *shft; int box[BOXELEM]; PIX_TYPE **pim, *picrt, *picrtk; IMAGE *imout; PIX_OUT *pout, *pocrt, delta; n = objectpix(imngb); if (n==ERROR){ (void)sprintf(buf,"mssgrad(): invalid imngb image!\n"); errputstr(buf); return NULL; } shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); for (i=0; i= nx) box[1] = 0; */ /* else box[1] = GetImNx(imngb) - 1 - ox; */ /* if (oy < 0) box[2] = 0; */ /* else box[2] = oy; */ /* if (oy >= ny) box[3] = 0; */ /* else box[3] = GetImNy(imngb) - 1 - oy; */ /* if (oz < 0) box[4] = 0; */ /* else box[4] = oz; */ /* if (oz >= nz) box[5] = 0; */ /* else box[5] = GetImNz(imngb) - 1 - oz; */ /* here we go */ lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; pout=(PIX_OUT *)GetImPtr(imout); for (z = box[4]; z < lstz; z++){ ofs = nx * ny * z; ofs += nx * box[2]; ofs += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ pocrt=pout+ofs; *pocrt=0; for (k = 0; k < n; k++){ delta=0.0; for (i=0; i*pocrt) *pocrt=delta; } *pocrt=(PIX_OUT)sqrt((double)*pocrt); ofs++; } ofs += box[0] + box[1]; } } free(pim); free((char *) shft); return(imout); } #include "uc_undef.h" /** * * * @param imap * @param nc * @param imngb image defining the neighbourhood with values in $\{0,1\}$ * @param ox integer for x-coordinate of origin of neighbourhood image * @param oy integer for x-coordinate of origin of neighbourhood image * @param oz integer for x-coordinate of origin of neighbourhood image * * @return multispectral gradient of input multi-channel image (up to 255 channels) using definition of \cite{soille96} and arbitrary neighbourhood. */ IMAGE *msgradlinfngb(IMAGE **imap, int nc, IMAGE *imngb, int ox, int oy, int oz) { switch (GetImDataType(*imap)){ case t_UCHAR: return(uc_msgradlinfngb(imap, nc, imngb, ox, oy, oz)); break; default: (void)sprintf(buf,"msgradlinfngb(): invalid pixel type\n"); errputstr(buf); return NULL; } return NULL; } jeolib-miallib-1.1.6/core/c/mspa.c000066400000000000000000000574501467232417700167000ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille and Peter Vogt Copyright (C) 2008-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** @file * Morphological Segmentation of Binary Patterns \cite soille-vogt2009 * https://doi.org/10.1016/j.patrec.2008.10.015 * @author Pierre Soille and Peter Vogt * Version 2.3, February 2022 */ #include #include #include #include #include "miallib.h" #include "op.h" extern ERROR_TYPE binOIthin_FIFO(IMAGE *imin, int stype, int atype, IMAGE *imanchor); extern IMAGE *ced(IMAGE *ref, IMAGE *mask); extern ERROR_TYPE dirmax(IMAGE *im, int dir); extern ERROR_TYPE label(IMAGE *im1, IMAGE *im2, int ox, int oy, int oz); extern ERROR_TYPE rdil(IMAGE *mark, IMAGE *mask, int graph, int flag); extern ERROR_TYPE rero(IMAGE *mark, IMAGE *mask, int graph, int flag); extern ERROR_TYPE set_regions(IMAGE *ilbl, IMAGE *ival, int indic); extern ERROR_TYPE f_threshstrict(IMAGE *, float, float, float, float); extern ERROR_TYPE i32_setlevel(IMAGE *, INT32, INT32, INT32); extern ERROR_TYPE i32_thresh(IMAGE *, INT32, INT32, INT32, INT32); extern ERROR_TYPE wsfah(IMAGE *iml, IMAGE *imr, int graph, int maxfl); IMAGE *getexternalboundary(IMAGE *im, float size, float edu) { IMAGE *nim, *imsqedt, *edt; nim=(IMAGE *)copy_image(im); negation(nim); imsqedt=(IMAGE *)sqedt(nim); uint32_to_float(imsqedt); edt=imsqedt; imsqrt(edt); f_thresh(edt, 0.0, size*edu, 0.0, 1.0); to_uchar(edt); bitwise_op(edt, nim, AND_op); free_image(nim); return(edt); } /*! * Image preparation assuming that the input iamge has 0 for no data, * 1 for background, and 2 for foreground pixels. */ IMAGE *fm_preproc(IMAGE *fm, float size, float edu) { IMAGE *da, *fa, *dda, *dfa; da=(IMAGE *)copy_image(fm); generic_thresh(da, 1, 255, 0, 1); /* 0 missing 1 for background 2 for foreground */ dda=getexternalboundary(da, size, edu); free_image(da); fa=(IMAGE *)copy_image(fm); generic_thresh(fa, 2, 255, 0, 1); dfa=getexternalboundary(fa, size, edu); arith(dfa, fa, OR_op); arith(dfa, dda, INF_op); arith(dfa, fa, SUP_op); free_image(fa); free_image(dda); return (dfa); } /*! * Add a frame of width equal to size and propagate the values of each * respective image border into the frame to mitigate border effects. */ IMAGE *fm_preproc2(IMAGE *im, int size) { IMAGE *lb, *rb, *tb, *bb, *bbim, *lbim, *rbim, *tbim; int box[6]; /* (lb (*imcut fm 0 0 0 0 (- (*getny fm) 1) 0)) */ lb=imcut(im, 0, 0, 0, 0, GetImNy(im)-1, 0); /* (lbim (*imcreate t_UCHAR size (*getny fm) 1)) */ lbim=create_image(t_UCHAR, size, GetImNy(im), 1); /* (rb (*imcut fm (- (*getnx fm) 1) */ /* 0 */ /* 0 */ /* (- (*getnx fm) 1) */ /* (- (*getny fm) 1) */ /* 0) */ /* ) */ rb=imcut(im, GetImNx(im)-1, 0, 0, GetImNx(im)-1, GetImNy(im)-1, 0); /* (rbim (*imcreate t_UCHAR size (*getny fm) 1)) */ rbim=create_image(t_UCHAR, size, GetImNy(im), 1); /* (tb (*imcut fm */ /* 0 */ /* 0 */ /* 0 */ /* (- (*getnx fm) 1) */ /* 0 */ /* 0) */ /* ) */ tb=imcut(im, 0, 0, 0, GetImNx(im)-1, 0, 0); /* (tbim (*imcreate t_UCHAR (*getnx fm) size 1)) */ tbim=create_image(t_UCHAR, GetImNx(im), size, 1); /* (bb (*imcut fm */ /* 0 */ /* (- (*getny fm) 1) */ /* 0 */ /* (- (*getnx fm) 1) */ /* (- (*getny fm) 1) */ /* 0) */ /* ) */ bb=imcut(im, 0, GetImNy(im)-1, 0, GetImNx(im)-1, GetImNy(im)-1, 0); /* (bbim (*imcreate t_UCHAR (*getnx fm) size 1)) */ bbim=create_image(t_UCHAR, GetImNx(im), size, 1); /* (out (*addframebox fm size size size size 0 0 0)) */ box[0]=box[1]=box[2]=box[3]=size; box[4]=box[5]=0; generic_addframebox(im, box, 0); /* (@imputop out (@dirmax (@imputintop lbim lb */ /* (- (*getnx lbim) 1) */ /* 0 */ /* 0 */ /* OR_op) */ /* 3) */ /* 0 size 0 */ /* OR_op) */ imputop(lbim, lb, GetImNx(lbim)-1, 0, 0, OR_op); dirmax(lbim, 3); imputop(im, lbim, 0, size, 0, 11); /* (@imputop out (@dirmax (@imputintop rbim rb */ /* 0 */ /* 0 */ /* 0 */ /* OR_op) */ /* 1) */ /* (- (*getnx out) size 1) */ /* size */ /* 0 */ /* OR_op) */ imputop(rbim, rb, 0, 0, 0, 11); dirmax(rbim, 1); imputop(im, rbim, GetImNx(im)-size-1, size, 0, OR_op); /* (@imputop out (@dirmax (@imputintop tbim tb */ /* 0 */ /* (- (*getny tbim) 1) */ /* 0 */ /* OR_op) */ /* 0) */ /* size */ /* 0 */ /* 0 */ /* OR_op) */ imputop(tbim, tb, 0, GetImNy(tbim)-1, 0, OR_op); dirmax(tbim, 0); imputop(im, tbim, size, 0, 0, 11); /* (@imputop out (@dirmax (@imputintop bbim bb */ /* 0 */ /* 0 */ /* 0 */ /* OR_op) */ /* 2) */ /* size */ /* (- (*getny out) size 1) */ /* 0 */ /* OR_op) */ imputop(bbim, bb, 0, 0, 0, 11); dirmax(bbim, 2); imputop(im, bbim, size, GetImNy(im)-size -1 , 0, OR_op); free_image(rb); free_image(lb); free_image(bb); free_image(tb); free_image(rbim); free_image(lbim); free_image(tbim); free_image(bbim); return im; } /*! * Give an input binary image, returns those foreground pixels that * are further away than a distance threshold (size in pixel units) * from the boundary of the foreground pixels. */ IMAGE *getcore(IMAGE *im, float size, float edu) { IMAGE *imsqedt, *edt; imsqedt=(IMAGE *)sqedt(im); uint32_to_float(imsqedt); edt=imsqedt; imsqrt(edt); //f_thresh(edt, (size*edu) + 0.001, 65535.0, 0.0, 1.0); f_threshstrict(edt, (size*edu), 65535.0, 0.0, 1.0); to_uchar(edt); return(edt); } IMAGE *getpatch(IMAGE *im, float size, int graphfg, float edu) { IMAGE *core; /* (*sub im (@rdil (*getcore im size) */ /* im */ /* graphfg) */ /* ) */ /* ) */ core=getcore(im, size, edu); rdil(core, im, graphfg, 1); arith(core, im, SUBSWAP_op); return(core); } IMAGE *uc_fillhole(IMAGE *im, int graph) { IMAGE *marker; int box[BOXELEM]; BOX_2D; marker=create_image(t_UCHAR, GetImNx(im), GetImNy(im), 1); generic_blank(marker,255); generic_framebox(marker,box,0); arith(marker, im, SUP_op); rero(marker, im, graph, 1); return marker; } IMAGE **setedges(IMAGE *im, float size, int graphfg, int graphbg, float edu) { IMAGE **iml; IMAGE *core, *outer, *corefill, *loecher, *edges, *core1=NULL; IMAGE *crt_edges; IMAGE *i0; int counter; core=getcore(im, size, edu); core1=copy_image(core); corefill=uc_fillhole(core, graphbg); loecher=copy_image(corefill); arith(loecher, core, SUB_op); edges=create_image(t_UCHAR, GetImNx(im), GetImNy(im), 1); iml=calloc(2,sizeof(IMAGE *)); for(counter=0;;counter++){ volume(corefill); // printf("volume=%d\n", (int)GetImVol(corefill)); if (GetImVol(corefill)==0.0) break; crt_edges=getexternalboundary(corefill, size, edu); bitwise_op(edges, crt_edges, OR_op); free_image(crt_edges); i0=uc_fillhole(loecher, graphfg); free_image(loecher); arith(corefill, i0, SUB_op); free_image(i0); arith(core, corefill, SUB_op); free_image(corefill); corefill=uc_fillhole(core, graphbg); loecher=copy_image(corefill); arith(loecher, core, SUB_op); } iml[0]=edges; outer=getexternalboundary(core1, size, edu); negation(core1); bitwise_op(edges, core1, AND_op); free_image(core1); arith(outer, edges, SUB_op); iml[1]=outer; free_image(core); free_image(corefill); free_image(loecher); return iml; } IMAGE *getexternalboundarygeodesic(IMAGE *im, IMAGE *mask, float size, float edu) { //(defun *getexternalboundarygeodesic (im mask size) // (@touchar // (@thresh // (*ced im mask) // 0.0001 // (+ (* size edu)) // 0.0 1.0) // ) // ) IMAGE *imdst; imdst=(IMAGE *)ced(im, mask); f_thresh(imdst, 0.0001, size*edu, 0.0, 1.0); to_uchar(imdst); return imdst; } IMAGE *getconnector2core(IMAGE *core, IMAGE *opening, IMAGE *residues, float size, int oitype, int graphfg, float edu) { // (let* ( // (sk (@sub (@binanchorskeloi (*or opening residues) core oitype) // core) // ) // ; (connector (*getexternalboundary sk (- size 1))) ; should be geodesic // (connector (*getexternalboundarygeodesic sk // (@or (*sub opening core) residues) // (- size 1))) ; should be geodesic // ) // (@and (@or connector sk) (@or (*sub opening core) residues) ) // ; we need to intersect with reconstruction // (@and connector (*rdil sk (@or (*sub opening core) residues) graphfg)) // // ) IMAGE *sk, *connector, *i0; sk=copy_image(opening); bitwise_op(sk, residues, OR_op); binOIthin_FIFO(sk, oitype, 1, core); arith(sk, core, SUB_op); i0=copy_image(opening); arith(i0, core, SUB_op); bitwise_op(i0, residues, OR_op); connector=getexternalboundarygeodesic(sk, i0, size-1, edu); bitwise_op(connector, sk, OR_op); bitwise_op(connector, i0, AND_op); rdil(sk, i0, graphfg, 1); bitwise_op(connector, sk, AND_op); free_image(sk); free_image(i0); return connector; } /* (defun *getcorridor (connector core opening size oitype) */ /* (let* ( */ /* (cor (@setregions (@labelgraph (*tolong connector) graphfg) */ /* (*wsfah */ /* (*labelgraph (*tolong core) graphfg) */ /* (@setlevel (*or opening connector) 0 0 255) */ /* graphfg 254) */ /* 20)); 20 for range */ /* ) */ /* (@setlevel cor 2147483647 2147483647 0) */ /* (@thresh cor 1 2147483647 0 1) */ /* (@touchar cor) */ /* ) */ /* ) */ IMAGE *getcorridor(IMAGE *connector, IMAGE *core, IMAGE *opening, float size, int oitype, int graph) { IMAGE *lbl, *imref, *cor; IMAGE *se; unsigned char *pse; se=create_image(t_UCHAR, 3, 3, 1); pse=(unsigned char *)GetImPtr(se); pse[1]=1; pse[3]=1; pse[5]=1; pse[7]=1; if (graph==8){ pse[0]=1; pse[2]=1; pse[6]=1; pse[8]=1; } lbl=to_int32(core); lbl->DataType = t_UINT32; label(lbl, se, 1, 1, 0); imref=copy_image(opening); bitwise_op(imref, connector, OR_op); generic_setlevel(imref, 0, 0, 255); lbl->DataType=t_UINT32; wsfah(lbl, imref, graph, 254); free_image(imref); cor=to_int32(connector); cor->DataType = t_UINT32; label(cor, se, 1, 1, 0); cor->DataType = t_INT32; lbl->DataType=t_INT32; set_regions(cor, lbl, 20); // 20 for range free_image(lbl); i32_setlevel(cor, 2147483647, 2147483647, 0); i32_thresh(cor, 1, 2147483647, 0, 1); to_uchar(cor); free_image(se); return cor; } //void fsp(char fnin[], char fnout[], float size, int graphfg, int disk, int transition, int internal) IMAGE *segmentBinaryPatterns(IMAGE *imin, float size, int graphfg, int transition, int internal) { IMAGE *im, *i0, *core, *patch; IMAGE *allHoles, *coreHoles; IMAGE *opening, *edges, *perforation, *residues; IMAGE *connector, *shortcut, *corridor; IMAGE **iml; IMAGE *tmp, *tmp2; IMAGE *out; int disk = 0; /* use 1 to store intermediate results on disk: no files can be written for interapro */ float edu = sqrt(2.0); /* fixed value */ int index; int box[6]; int graphbg, oitype; // char desc[512]; int bufsize; sprintf(buf, "\nBased on Morphological Segmentation of Binary Patterns\n" "by Pierre Soille and Peter Vogt\n" "URL http://dx.doi.org/10.1016/j.patrec.2008.10.015\n" "File generated by mspa v2.2\n" "Parameters: size=%f, graphfg=%d, transition=%d internal=%d", size, graphfg, transition, internal); size=(size+0.98)/sqrt(2); if (graphfg==8){ graphbg=4; oitype=0; } else{ graphbg=8; oitype=1; } if ( (size==1) && (transition==2) ) transition=0; im = copy_image(imin); // (setq bufsize (truncate (+ 0.5 (* size 1.5)))) // (@fm_frame_in im bufsize) bufsize=(int)((size*1.5)+0.5); box[0]=box[1]=box[2]=box[3]=(int)(bufsize+1.5); box[4]=box[5]=0; generic_addframebox(im, box, 0); // get all holes if (internal==1){ i0=fm_preproc(im, 1, edu); allHoles=uc_fillhole(i0, graphbg); arith(allHoles, i0, SUB_op); //writeTiffOneStripPerLine(allHoles, "allHoles.tif", NULL); //free_image(allHoles); } // (setq i0 (*fm_preproc im size)) i0=fm_preproc(im, size, edu); free_image(im); // (@fm_frame_out i0 bufsize) subframebox(i0, box); // (setq i0 (*fm_preproc2 i0 (+ 1 bufsize))) fm_preproc2(i0, bufsize+1); out=copy_image(i0); box[0]=box[1]=box[2]=box[3]=1; box[4]=box[5]=0; box[0]=box[1]=box[2]=box[3]=(int)(bufsize+1.5); box[4]=box[5]=0; // (setq core (*getcore i0 size)) core=getcore(i0, size, edu); //(setq patch (*getpatch i0 size graphfg)) patch=getpatch(i0, size, graphfg, edu); // (setq outer (*getexternalboundary core size)) // (setq opening (*add outer core)) opening=getexternalboundary(core, size, edu); arith(opening, core, ADD_op); // (setq iml (*setedges i0 size)) // (setq edges (car iml)) // (setq perforation (cadr iml)) if (disk==1){ writeTiffOneStripPerLine(out, "disk_out.tif", NULL); free_image(out); writeTiffOneStripPerLine(patch, "disk_patch.tif", NULL); free_image(patch); writeTiffOneStripPerLine(opening, "disk_opening.tif", NULL); free_image(opening); writeTiffOneStripPerLine(core, "disk_core.tif", NULL); free_image(core); } iml=setedges(i0, size, graphfg, graphbg, edu); edges=iml[0]; perforation=iml[1]; // (setq residues (*sub i0 core patch perforation edges)) residues=i0; if (disk==1){ out=(IMAGE *)read_image("disk_out.tif"); patch=(IMAGE *)read_image("disk_patch.tif"); opening=(IMAGE *)read_image("disk_opening.tif"); core=(IMAGE *)read_image("disk_core.tif"); // remove("disk_core.tif"); remove("disk_core1.tif"); // remove("disk_opening.tif"); remove("disk_patch.tif"); remove("disk_out.tif"); } arith(residues, core, SUB_op); arith(residues, patch, SUB_op); shift(patch, -3); bitwise_op(out, patch, OR_op); free_image(patch); arith(residues, perforation, SUB_op); shift(perforation, -2); bitwise_op(out, perforation, OR_op); free_image(perforation); arith(residues, edges, SUB_op); shift(edges, -1); bitwise_op(out, edges, OR_op); free_image(edges); // (if (= transition 2) // (progn // (setq connector (*getconnector2opening opening residues size oitype)) // (setq corridor (*getcorridor2 connector opening size oitype)) // ) // (progn // (setq connector (*getconnector2core core opening residues size oitype)) // (setq corridor (*getcorridor connector core opening size oitype)) // ) // ) if (disk==1){ writeTiffOneStripPerLine(out, "disk_out.tif", NULL); free_image(out); // writeTiffOneStripPerLine(core, "disk_core.tif", NULL); free_image(core); // writeTiffOneStripPerLine(opening, "disk_opening.tif", NULL); free_image(opening); writeTiffOneStripPerLine(residues, "disk_residues.tif", NULL); free_image(residues); } connector=getconnector2core(core, opening, residues, size, oitype, graphfg, edu); if( (size!=1) && (disk!=1) ) free_image(residues); if (disk==1){ out=(IMAGE *)read_image("disk_out.tif"); core=(IMAGE *)read_image("disk_core.tif"); opening=(IMAGE *)read_image("disk_opening.tif"); if (size==1) residues=(IMAGE *)read_image("disk_residues.tif"); remove("disk_out.tif"); remove("disk_core.tif"); remove("disk_opening.tif"); remove("disk_residues.tif"); } corridor=getcorridor(connector, core, opening, size, oitype, graphfg); free_image(opening); shift(core, -4); bitwise_op(out, core, OR_op); if(internal!=1) free_image(core); // (setq shortcut (*sub connector corridor)) arith(connector, corridor, SUB_op); shortcut=connector; if (size == 1){ tmp=copy_image(corridor); dilate4(tmp, 1, 1); arith(tmp, residues, INF_op); bitwise_op(corridor, tmp, OR_op); free_image(tmp); // (@and corridor (@setlevel (@prune (@setlevel (*or opening corridor) 1 1 2) 2 4) // 2 2 1) // ) tmp=copy_image(shortcut); dilate4(tmp, 1, 1); arith(tmp, residues, INF_op); free_image(residues); bitwise_op(shortcut, tmp, OR_op); free_image(tmp); } // (@and shortcut (@setlevel (@prune (@setlevel (*or opening shortcut) 1 1 2) 2 4) // 2 2 1) // ) // ;; end of patch // generate output shift(corridor, -5); shift(shortcut, -6); bitwise_op(out, corridor, OR_op); free_image(corridor); bitwise_op(out, shortcut, OR_op); free_image(shortcut); if (internal==1){ shift(core, 4); tmp=uc_fillhole(core, graphbg); // allHoles=(IMAGE *)read_image("allHoles.tif"); // remove("allHoles.tif"); coreHoles=copy_image(tmp); arith(coreHoles, core, SUB_op); negation(coreHoles); bitwise_op(allHoles, coreHoles, AND_op); /* A \ B=A \int (\complement B) */ free_image(coreHoles); generic_setlevel(allHoles, 1, 1, 220); arith(tmp, core, SUB_op); free_image(core); tmp2=uc_fillhole(tmp, graphbg); generic_setlevel(tmp2, 1, 1, 100); arith(out, tmp2, ADD_op); arith(out, allHoles, SUP_op); free_image(allHoles); free_image(tmp); free_image(tmp2); } create_lut(out); index=0; out->lut[index]=56540; out->lut[index+256]=56540; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=56540; /* assuming 256 entries in ColorMap! */ index=100; out->lut[index]=35000; out->lut[index+256]=35000; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=35000; /* assuming 256 entries in ColorMap! */ index=1; out->lut[index]=65535; out->lut[index+256]=35980; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=101; out->lut[index]=65535; out->lut[index+256]=35980; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=3; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=103; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=5; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=105; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=9; out->lut[index]=41120; out->lut[index+256]=15420; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=109; out->lut[index]=41120; out->lut[index+256]=15420; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=17; out->lut[index]=0; out->lut[index+256]=51400; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=117; out->lut[index]=0; out->lut[index+256]=51400; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=33; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=133; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=65; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=165; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=129; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=220; out->lut[index]=50000; out->lut[index+256]=50000; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=50000; /* assuming 256 entries in ColorMap! */ if (transition==1){ index=35; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=135; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=67; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=167; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=37; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=137; out->lut[index]=65535; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=69; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=169; out->lut[index]=65535; out->lut[index+256]=65535; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ } else{ index=35; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=135; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=67; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=167; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=0; /* assuming 256 entries in ColorMap! */ index=37; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=137; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=69; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ index=169; out->lut[index]=0; out->lut[index+256]=0; /* assuming 256 entries in ColorMap! */ out->lut[index+512]=65535; /* assuming 256 entries in ColorMap! */ } // (@fm_postproc control im) // (@fm_frame_out control bufsize) box[0]=box[1]=box[2]=box[3]=(int)(bufsize+1); box[4]=box[5]=0; subframebox(out, box); im = copy_image(imin); generic_thresh(im, 1, 255, 129, 0); arith(out, im, MASK_op); free_image(im); return(out); } jeolib-miallib-1.1.6/core/c/myhull.cc000066400000000000000000000251731467232417700174120ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Pieter Kempeneers (repaced ut_vector with std::vector and re-implemented chainHull_2D for license) Copyright (C) 2010-2024 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* first 20101004 for convex hull and enclosing rectangle for building detection */ #include #include #include #include #include #include #include #include "myhull.h" extern "C" { #include "miallib.h" #include "fifo.h" } #ifdef OPENMP #include #endif // Function to find the convex hull using Andrew's monotone chain algorithm std::vector chainHull_2D(std::vector& points){ std::sort(points.begin(), points.end(), [](const intpair_t& a, const intpair_t& b) { return a.a < b.a || (a.a == b.a && a.b < b.b); }); auto orientation = [](intpair_t p, intpair_t q, intpair_t r){ return (q.b - p.b) * (r.a - q.a) - (q.a - p.a) * (r.b - q.b); }; std::vector hull; // Build lower hull for (const intpair_t& p : points){ while (hull.size() >= 2 && orientation(hull[hull.size() - 2], hull[hull.size() - 1], p) <= 0){ hull.pop_back(); } hull.push_back(p); } // Build upper hull for (int i = points.size() - 2, t = hull.size() + 1; i >= 0; i--){ const intpair_t& p = points[i]; while (hull.size() >= t && orientation(hull[hull.size() - 2], hull[hull.size() - 1], p) <= 0){ hull.pop_back(); } hull.push_back(p); } // Remove duplicates from hull hull.pop_back(); return hull; } // #include int intsort(const void *a,const void*b) { int _a = *(int*)a; int _b = *(int*)b; return _a - _b; } // int intpairsort(const void *a,const void*b) { // intpair_t _a = *(intpair_t*)a; // intpair_t _b = *(intpair_t*)b; // return _a.a < _b.a || (_a.a == _b.a && _a.b < _b.b); // } // extern double polygonArea(intpair_t *P, int points); // extern int chainHull_2D( intpair_t * P, int n, intpair_t * H ); /** \addtogroup group_opclo * @{ */ #include "u32_def.h" #define MY_LUT_TYPE UINT32 #define t_MY_LUT_TYPE t_UINT32 IMAGE *u32_chull(IMAGE *ilbl, int graph) { /* Processing based on contour representation: only points with change of direction are kept. Use MSB for flagging. assumes border is set to zero to avoid border overflow. Pierre Soille First 20100930 (for building footprint characterisation) Pieter Kempeneers 13/09/2024: replace utarray with c++ std::vector and reimplement hull for license issue based on Moore's contour tracing algorithm with Jacob's condition, see http://www.thebigblob.com/moore-neighbor-contour-tracing-algorithm-in-c/ by Erik Smistad (see local file moore_tracing.c) extended for label images as well as omp speed-up and graph. Also, speed-up since I start always from ulcx! Additional image not actually necessary (coding in MSB is enough) but used to return an image with mask of outer edge pixels set to 1 (others to 0). */ G_TYPE *pg; IMAGE *lut; MY_LUT_TYPE *plut; PIX_TYPE *plbl, maxlbl, lbl; IMAGE *imout; UCHAR *pout; int nx=GetImNx(ilbl); long int i, npix, pos; // openMP requires signed loop index // Defines the neighborhood offset position from current position and the neighborhood // position we want to check next if we find a new border at checkLocationNr // 1 2 3 // 0 x 4 // 7 6 5 int neighborhood[8][2] = { {-1,7}, // red {-1-nx,7}, // green {-nx,1}, // blue {-nx+1,1}, // yellow {1,3}, // magenta {1+nx,3}, // cyan {nx,5}, // white {nx-1,5} // grey }; if (graph!=8) graph=4; if (graph==4){ // - 1 - // 0 x 2 // - 3 - neighborhood[0][0] = -1; // red neighborhood[0][1] = 4; neighborhood[1][0] = -nx; // green neighborhood[1][1] = 1; neighborhood[2][0] = 1; // blue neighborhood[2][1] = 2; neighborhood[3][0] = nx; // yellow neighborhood[3][1] = 3; } imout=(IMAGE *)create_image(t_UCHAR, GetImNx(ilbl), GetImNy(ilbl), 1); if (imout==NULL) return NULL; /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); lut= (IMAGE *)create_image(t_MY_LUT_TYPE, maxlbl+1, 1, 1); if (lut==NULL){ free_image(imout); return NULL; } plut =(MY_LUT_TYPE *)GetImPtr(lut); plbl =(PIX_TYPE *)GetImPtr(ilbl); pout =(UCHAR *)GetImPtr(imout); npix =GetImNPix(ilbl); plut[0]=1; // dummy value to speed-up next loop /* first collect first point of each CC in an array for subsequent parallel processing */ for (i=0;i ph; int j; // utarray_new(pairs,&intpair_icd); std::vector pairs; // utarray_new(pairs,&intpair_icd); if (startPos!=0){ lbl=plbl[startPos]; //IFMSB plbl[startPos]|=PIX_MSB; // mark pixel as border pout[startPos]=9; // mark pixel as border pos=startPos; // Trace around the neighborhood while(1){ checkPosition = pos + neighborhood[checkLocationNr-1][0]; newCheckLocationNr = neighborhood[checkLocationNr-1][1]; if( plbl[checkPosition] == lbl) { // Next border point found if(checkPosition == startPos){ pout[pos]=checkLocationNr; // direction of next border point // set to 9 if point of change of direction if (checkLocationNr!=prevCheckLocationNr){ pout[pos]=9; pout[checkPosition]=9; prevCheckLocationNr=checkLocationNr; ip.a=pos%nx; // x coor ip.b=pos/nx; // y coor pairs.push_back(ip); // utarray_push_back(pairs, &ip); n++; } counter ++; // Stopping criterion (jacob) if(newCheckLocationNr == 1 || counter >= 1) { // Close loop break; } } pout[pos]=checkLocationNr; // direction of next border point // set to 9 if point of change of direction if (checkLocationNr!=prevCheckLocationNr){ pout[pos]=9; pout[checkPosition]=9; prevCheckLocationNr=checkLocationNr; ip.a=pos%nx; // x coor ip.b=pos/nx; // y coor pairs.push_back(ip); // utarray_push_back(pairs, &ip); n++; } checkLocationNr = newCheckLocationNr;// Update which neighborhood position we should check next pos = checkPosition; counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited } else{ // Rotate clockwise in the neighborhood checkLocationNr = 1 + (checkLocationNr % graph); if(counter2 > graph){ // If counter2 is above 8 we have traced around the neighborhood and // therefore the border is a single black pixel and we can exit counter2 = 0; ip.a=pos%nx; // x coor ip.b=pos/nx; // y coor pairs.push_back(ip); // utarray_push_back(pairs, &ip); n++; break; } else{ counter2 ++; } } } //printf("n=%d\n", n); // ph=phori=(intpair_t *)calloc((size_t) n+1, sizeof(intpair_t)); ph.resize(n+1); // if (ph==NULL){ // printf("cannot allocate %ld bytes for point array in convex hull computation of lbl=%ud\n", \ // (n+1)*sizeof(intpair_t), lbl); // utarray_free(pairs); // continue; // } // utarray_sort(pairs, &intpairsort); // nh=chainHull_2D( (intpair_t *)utarray_eltptr(pairs, 0), n, ph ); ph = chainHull_2D(pairs); //printf("nh=%d\n", nh); for (auto it = ph.begin(); it!=ph.end(); ++it) pout[it->a + it->b *nx] = 10; // for(j=0; j. ***********************************************************************/ /* ** Header file for myhull.cc */ #ifndef _MYHULL_H #define _MYHULL_H #include /* for point with integer coordinates */ typedef struct { int a; int b; } intpair_t; std::vector chainHull_2D(std::vector& points); #endif /* _MYHULL_H */jeolib-miallib-1.1.6/core/c/natngbint.c000066400000000000000000000206311467232417700177130ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #ifdef NNI #include #include #include #include /* installed in nn-c-master/nn */ #ifdef OPENMP #include #endif #include "miallib.h" #include /* installed from nn-c-master/nn */ #include /* installed from csa-c-master/csa */ /* Calls Pavel Sakov's code for nni (CSIRO Marine Research). This latter code relies itself on efficient triangle.c from Jonathan Richard Shewchuk, Berkeley California. Downloaded from googlecode on 20140226 adaptation by Pierre Soille from: nnpi_interpolate_points(int nin, point pin[], double wmin, int nout, point pout[]); does not require array pout (each output point calculated on the fly from grid structure) To be done: - upgrade triangle.c from current version 1.4 to version 1.6 available from Richard: https://www.cs.cmu.edu/~quake/triangle.html; - deal with NaN returned for points outside convex hull when wmin=0; - inverstigate www.netlib.org/vornoi. first: 20140226 first working: 20140226 */ /* Performs Natural Neighbours interpolation for an array of points. * * @param nin Number of input points * @param pin Array of input points [pin] * @param wmin Minimal allowed weight (0 to have interpolation inside of the convex hull of the points) * @param nout Number of output points * @param pout Array of output points [nout] */ #include "uc_def.h" IMAGE *uc_nni(IMAGE *im, IMAGE *imx, IMAGE *imy, double startx, double starty, double deltax, double deltay, int nx, int ny, double wmin) { IMAGE *imout; PIX_TYPE *pim, *pimout; double *px, *py; point *pin=NULL; point pout; int nin=(int)GetImNPix(im); int i; int x, y; pin=(point *)calloc(nin, sizeof(point)); if (pin==NULL){ printf("nni(): not enough memory for input point array\n"); return NULL; } imout=(IMAGE *)create_image(t_PIX_TYPE, nx, ny, 1); if(imout==NULL){ free(pin); return NULL; } pimout=(PIX_TYPE *)GetImPtr(imout); px=(double *)GetImPtr(imx); py=(double *)GetImPtr(imy); pim=(PIX_TYPE *)GetImPtr(im); #pragma omp parallel for private(i) for (i=0; i 0) csa_setnpmin(a, npmin); if (npmax > 0 && npmax > npmin) csa_setnpmax(a, npmax); if (k > 0.0) csa_setk(a, k); if (nppc > 0) csa_setnppc(a, nppc); /* * read input data into point array */ #pragma omp parallel for private(i) for (i = 0; i < nin; ++i) { p = &pin[i]; p->x = px[i]; p->y = py[i]; p->z = (double)pim[i]; } csa_addpoints(a, nin, pin); if (sigma != NULL) csa_addstd(a, nin, sigma); /* * calculate spline */ csa_calculatespline(a); /* * read output data into point array */ pout=(point *)calloc(nout, sizeof(point)); if (pout==NULL){ printf("grid_nnpi_interpolate_point(): not enough memory for input point array\n"); free(pin); free_image(imout); return NULL; } i=0; for(y=0; yx=startx+x*deltax; p->y=ycrt; p->z = NaN; } } /* * approximate */ csa_approximatepoints(a, nout, pout); /* * write results to the output array */ for (i = 0; i. ***********************************************************************/ #include #include #include #include "miallib.h" #include "pqueue.h" #include "fifo.h" #include "op.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define CC_LBL_TYPE UINT32 #define t_CC_LBL_TYPE t_UINT32 #define PIXCC_MSB 0x80000000 #define INACTIVE_BIT 0x40000000 #define PIXCC_LTSB 0xC0000000 #define PIXCC_LBLB 0x3FFFFFFF IMAGE *uc_labelccattr(IMAGE *im, int graph, int rg, int rl) { /* First 2011-09-21: for any attribute even non increasing like var and correct ... */ PIX_TYPE *p, val, mincc, maxcc; int exiso, flag; IMAGE *imlbl; CC_LBL_TYPE *plbl, lbl=2; unsigned long int npix, i, refofs, ofs, ofsk; int prio; long int k, *shft; int nx, ny, nz; FIFO4 *q; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; struct pqueue *pq; nx = GetImNx(im); ny = GetImNy(im); nz = GetImNz(im); npix=GetImNPix(im); imlbl= (IMAGE *)create_image(t_CC_LBL_TYPE, nx, ny, nz); if (imlbl == NULL){ (void)sprintf(buf,"_labelccdissim(): not enough memory!\n"); errputstr(buf); return NULL; } pq = pqinit(NULL, GetImNPix(imlbl)/100L); /* priority queue */ if (pq == NULL){ free_image(imlbl); return NULL; } if (graph!=4){ // only 4-connectivity for now free_image(imlbl); free_pq(pq); return NULL; } shft = (long int *)calloc(graph, sizeof(long int)); if (shft == NULL){ free_image(imlbl); free_pq(pq); return NULL; } shft[0]=-nx; shft[1]=-1; shft[2]=1; shft[3]=nx; q = create_fifo4(500); if (q == NULL){ free_image(imlbl); free_pq(pq); free((char*)shft); return NULL; } /* Take SE into account */ BOX_2D; u32_blank(imlbl,1); if (u32_framebox(imlbl,box,0)==ERROR){ free_image(imlbl); free_pq(pq); free((char*)shft); free_fifo4(q); return NULL; } /* scan the image while labelling 0-CCs and insert first pixel with priority equal to external isolation */ p = (PIX_TYPE *)GetImPtr(im); plbl= (CC_LBL_TYPE *)GetImPtr(imlbl); for (i=nx; iprio = exiso; pqd->val= lbl; pqd->offset= (long int)i; pqmininsert(pq, pqd); } lbl++; } } //u32_dumpxyz(imlbl, 0, 0, 0, 20 , 20); while (pqpeek(pq, apqd) != NULL){ pqminremove(pq, apqd); refofs=apqd[0]->offset; prio=apqd[0]->prio; lbl=apqd[0]->val; free((char*) *apqd); if(plbl[refofs]==lbl){ /* still active: compute prio-CC of refofs */ plbl[refofs]|=PIXCC_MSB; fifo4_add(q, (long int)refofs); mincc=maxcc=p[refofs]; flag=0; while ( (ofs=fifo4_remove(q)) ){ for (k=0; kp[ofsk]){ mincc=p[ofsk]; if ((maxcc-mincc)>rg){ flag=1; } } else if (maxccrg){ flag=1; } } } plbl[ofsk]|=PIXCC_MSB; fifo4_add(q, (long int)ofsk); } } } } if (flag==1){ /* reset visited prio-CC to inactive */ plbl[refofs]^=PIXCC_LTSB; fifo4_add(q, (long int)refofs); while ( (ofs=fifo4_remove(q)) ){ for (k=0; kprio=exiso; pqd->val=lbl; pqd->offset=(long int)refofs; pqmininsert(pq, pqd); } } } } #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i. ***********************************************************************/ /** * @file oiht.c * @author Pierre SOILLE * @date Wed Aug 10 14:03:41 2016 * * @details see also \cite ranwez-soille99 and \cite ranwez-soille2002 */ #include #include #include #include "miallib.h" /** \addtogroup group_hmtsk * @{ */ #define OIHTLABEL_TYPE int extern void free_image(IMAGE *); extern IMAGE *copy_image(IMAGE *); extern ERROR_TYPE rdil(IMAGE *, IMAGE *, int, int); extern ERROR_TYPE generic_blank(IMAGE *, UCHAR ); extern ERROR_TYPE i32_label(IMAGE *, IMAGE *, int, int, int ); extern IMAGE *to_int32(IMAGE *); extern ERROR_TYPE szcompat(IMAGE *, IMAGE *); extern ERROR_TYPE generic_addframebox(IMAGE *, int *, UCHAR); extern ERROR_TYPE us_addframebox(IMAGE *, int *, USHORT); extern ERROR_TYPE subframebox(IMAGE *, int *); extern G_TYPE *min_max(IMAGE *); #include "uc_def.h" int ronsetest(IMAGE *pm1, IMAGE *pmsimple, int pix1, IMAGE *pmlabel, int* neighbours) /* remove all simple pixels as long as potentially new one appears */ /* the anchor image indicates the pixels which cannot be removed */ { int label=0; int i,j; IMAGE *seed=copy_image(pm1); PIX_TYPE *ppm1=(PIX_TYPE *)GetImPtr(pm1); PIX_TYPE *pseed=(PIX_TYPE *)GetImPtr(seed); PIX_TYPE *ppmsimple=(PIX_TYPE *)GetImPtr(pmsimple); OIHTLABEL_TYPE *ppmlabel=(OIHTLABEL_TYPE *)GetImPtr(pmlabel); generic_blank(seed, 0); for(i=0;i<4;i++) if(ppm1[pix1+neighbours[i]] == 0 ) label = ppmlabel[pix1+neighbours[i]]; pseed[pix1]=1; rdil(seed,pm1, 8, 1); /* CC(pm2,pix1,8);*/ pseed=(PIX_TYPE *)GetImPtr(seed); /* pseed redefined in rdil !!! */ ppm1=(PIX_TYPE *)GetImPtr(pm1); /* ppm1 redefined in rdil !!! */ for( i=0; i= ng)){ minNG=ppm1NG[i]; if ( minNG==ng) i=GetImNPix(pm1NG); } } ng=minNG; for( i=0; i1) /* at this stage, anchor points are used for binary only */ panchor[i]=0; if(ppm1NG[i] ng ) panchor[i]=1; ppm1[i]=1; } } #ifdef DEBUB printf("pm1 after initial threshold \n"); dumpxyz(pm1, 5, 5, 0, 20, 20); #endif if (pmlabel!=NULL) free_image(pmlabel); pm1not=copy_image(pm1); negation(pm1not); generic_addframebox(pm1not, box, 1); pmlabel = to_int32(pm1not); i32_label(pmlabel, imse, 1, 1, 0); subframebox(pmlabel, box); free_image(pm1not); ppmlabel = (OIHTLABEL_TYPE *)GetImPtr(pmlabel); /* initialising the set of removable pixels ie (simple and not anchor point). */ ind[0]=0; ind[1]=0; use=0; for ( i=0 ; i minNG) ) minNG = ppmcrt[pix1+neighbours[j]]; ppm1NG[pix1]=minNG; for(j=0;j<4;j++) if (ppm1[pix1+neighbours[j]]==0) ppmlabel[pix1]=ppmlabel[pix1+neighbours[j]]; } } /* for each removable pixels */ free_image(pmcrt); free_image(pmlabelcrt); ind[use]=0; for ( i=0 ; i= ng)){ minNG=ppm1NG[i]; if ( minNG==ng) i=GetImNPix(pm1NG); } } ng=minNG; #ifdef DEBUB printf("ng=%d\n",ng); #endif for( i=0; i ng ) panchor[i]=1; ppm1[i]=1; } } #ifdef DEBUB printf("pm1 after initial threshold \n"); us_dumpxyz(pm1, 5, 5, 0, 20, 20); #endif if (pmlabel!=NULL) free_image(pmlabel); pm1not=copy_image(pm1); negation(pm1not); generic_addframebox(pm1not, box, 1); pmlabel = to_int32(pm1not); i32_label(pmlabel, imse, 1, 1, 0); subframebox(pmlabel, box); free_image(pm1not); ppmlabel = (OIHTLABEL_TYPE *)GetImPtr(pmlabel); /* initialising the set of removable pixels ie (simple and not anchor point). */ ind[0]=0; ind[1]=0; use=0; for ( i=0 ; i minNG) ) minNG = ppmcrt[pix1+neighbours[j]]; ppm1NG[pix1]=minNG; for(j=0;j<4;j++) if (ppm1[pix1+neighbours[j]]==0) ppmlabel[pix1]=ppmlabel[pix1+neighbours[j]]; } } /* for each removable pixels */ free_image(pmcrt); free_image(pmlabelcrt); ind[use]=0; for ( i=0 ; i= ng)){ minNG=ppm1NG[i]; if ( minNG==ng) i=GetImNPix(pm1NG); } } ng=minNG; #ifdef DEBUB printf("ng=%d\n",ng); #endif memcpy((void *)panchorcrt, (void *)panchor, (size_t)GetImNPix(imanchor)); for( i=0; i ng ) panchorcrt[i]=1; ppm1[i]=1; } } #ifdef DEBUB printf("pm1 after initial threshold \n"); dumpxyz(pm1, 5, 5, 0, 20, 20); #endif if (pmlabel!=NULL) free_image(pmlabel); pm1not=copy_image(pm1); negation(pm1not); generic_addframebox(pm1not, box, 1); pmlabel = to_int32(pm1not); i32_label(pmlabel, imse, 1, 1, 0); subframebox(pmlabel, box); free_image(pm1not); ppmlabel = (OIHTLABEL_TYPE *)GetImPtr(pmlabel); /* initialising the set of removable pixels ie (simple and not anchor point). */ ind[0]=0; ind[1]=0; use=0; for ( i=0 ; i minNG) ) minNG = ppmcrt[pix1+neighbours[j]]; ppm1NG[pix1]=minNG; for(j=0;j<4;j++) if (ppm1[pix1+neighbours[j]]==0) ppmlabel[pix1]=ppmlabel[pix1+neighbours[j]]; } } /* for each removable pixels */ free_image(pmcrt); free_image(pmlabelcrt); ind[use]=0; for ( i=0 ; i= ng)){ minNG=ppm1NG[i]; if ( minNG==ng) i=GetImNPix(pm1NG); } } ng=minNG; #ifdef DEBUB printf("ng=%d\n",ng); #endif memcpy((void *)panchorcrt, (void *)panchor, (size_t)GetImNPix(imanchor)*sizeof(PIX_TYPE)); for( i=0; i ng ) panchorcrt[i]=1; ppm1[i]=1; } } #ifdef DEBUB printf("pm1 after initial threshold \n"); us_dumpxyz(pm1, 5, 5, 0, 20, 20); #endif if (pmlabel!=NULL) free_image(pmlabel); pm1not=copy_image(pm1); negation(pm1not); generic_addframebox(pm1not, box, 1); /* was us_ */ pmlabel = to_int32(pm1not); i32_label(pmlabel, imse, 1, 1, 0); subframebox(pmlabel, box); free_image(pm1not); ppmlabel = (OIHTLABEL_TYPE *)GetImPtr(pmlabel); /* initialising the set of removable pixels ie (simple and not anchor point). */ ind[0]=0; ind[1]=0; use=0; for ( i=0 ; i minNG) ) minNG = ppmcrt[pix1+neighbours[j]]; ppm1NG[pix1]=minNG; for(j=0;j<4;j++) if (ppm1[pix1+neighbours[j]]==0) ppmlabel[pix1]=ppmlabel[pix1+neighbours[j]]; } } /* for each removable pixels */ free_image(pmcrt); free_image(pmlabelcrt); ind[use]=0; for ( i=0 ; i maxmin) maxmin=ppmNG[i + neighbours[j]]; if ( ppmlabel[i + neighbours[j]] != label){ free_image(seed); return(0); } } } } } } /* We have a simply connected component of simple pixels */ /* We set all pixels to the maximal value (maxmin) of the neighbours */ for( i=0; i maxmin) maxmin=ppmNG[i + neighbours[j]]; if ( ppmlabel[i + neighbours[j]] != label){ free_image(seed); return(0); } } } } } } /* We have a simply connected component of simple pixels */ /* We set all pixels to the maximal value (maxmin) of the neighbours */ for( i=0; i. ***********************************************************************/ /* First Tue Feb 24 2004 */ #include #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_hmtsk * @{ */ /* The code below runs for an order independent (binary) iz */ #include "g_def.h" ERROR_TYPE generic_oiiz(IMAGE *im) { /* We propose to simulate an order independent flooding based on ordered indenpendent thinnings proceeding by increasing intensity levels. */ long int i, j, ofs, ofs2; int del; /* Bool. variable ind. whether a pixel is deletable (1) or not (0) */ int si; /* Bool. variable ind. whether a pixel is strictly ind. (1) or not (0) of a given simple ngb */ int nsi; /* Bool. variable ind. whether a pixel is non-strictly ind. (1) or not (0) of all its simple ngb */ int cfg; /* Bool. variable ind. whether there is a common foreground neighbour */ int nsn; /* Bool. variable ind. whether there exists a pixel is non-simple ngb */ int code; int nx=GetImNx(im); long int npix=GetImNPix(im); int box[6]; int homotab[256] = { 0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,1,\ 1,0,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1,1,0,1,0,\ 1,0,1,1,1,1,0,0,1,1,0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,0,1,1,0,0,0,0,\ 0,0,1,0,1,0,0,1,1,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,1,0,1,0,\ 0,0,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,0,\ 0,0,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,0,0,0,\ 1,1,0,0,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,\ 1,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0}; int code8[48] = { 16, 4, 4, 64, 32, 8, 8, 128,\ 4, 16, 64, 4, 8, 32, 128, 8,\ 1, 32, 16, 1, 2, 128, 64, 2,\ 32, 1, 1, 16, 128, 2, 2, 64,\ 4, 2, 1, 8,\ 8, 2, 1, 4,\ 2, 8, 4, 1,\ 2, 4, 8, 1}; int code4[16]= { 4, 4, 8, 8, 4, 4, 8, 8,\ 1, 1, 2, 2, 1, 1, 2, 2}; int codei[8] = {1, 2, 4, 8, 16, 32, 64, 128}; int shft[8], shftcode[129]; int dep4, dep8, cn; int *ccode8, *ccode4; int count=0; IMAGE *imflag; /* image of flags */ UCHAR *pflag, *pcflag, *puc; PIX_TYPE *pim, *pcim, *pcim2, h, val; FIFO4 *q, *q2, *q3, *q4; /* create flag image */ imflag = (IMAGE *)create_image(t_UCHAR,GetImNx(im), GetImNy(im), GetImNz(im)); if (imflag==NULL) return(ERROR); /* avoid border effects by setting border pixels to PIX_MIN */ BOX_2D; generic_framebox(im, box, PIX_MIN); /* PIX_MIN => never simple */ /* create a queue */ q = create_fifo4(npix/100L); if (q == NULL){ (void) sprintf(buf, "oiiz(): not enough memory"); errputstr(buf); return ERROR; } q2 = create_fifo4(npix/100L); if (q2 == NULL){ (void) sprintf(buf, "oiiz(): not enough memory"); errputstr(buf); return ERROR; } q3 = create_fifo4(npix/100L); if (q3 == NULL){ (void) sprintf(buf, "oiiz(): not enough memory"); errputstr(buf); return ERROR; } q4 = create_fifo4(npix/100L); if (q4 == NULL){ (void) sprintf(buf, "oiiz(): not enough memory"); errputstr(buf); return ERROR; } /* initialise the queue with all simple pixels */ pim =(PIX_TYPE *)GetImPtr(im); pcim =pim; pflag =(UCHAR *)GetImPtr(imflag); pcflag =pflag; for (i=0; i=h) code=1; if (*(pcim+1)>=h) code|=2; if (*(pcim-nx)>=h) code|=4; if (*(pcim+nx)>=h) code|=8; if (*(pcim-nx-1)>=h) code|=16; if (*(pcim+nx-1)>=h) code|=32; if (*(pcim-nx+1)>=h) code|=64; if (*(pcim+nx+1)>=h) code|=128; if (homotab[code]){ fifo4_add(q, pcim-pim); /* insert offset position */ *pcflag=code; count++; } else if (code == 0){ /* isolated pixel (non-simple but deletable for IZ/WS) */ /* add in queue of ordered independent pixels */ *pcim=0; /* fifo4_add(q2, pcim-pim); CHECK!!! */ } } } printf("count (number of simple border pixels at init)=%d\n", count); count=0; shft[0]=-1; shft[1]=1; shft[2]=-nx; shft[3]=nx; shft[4]=-nx-1; shft[5]=nx-1; shft[6]=-nx+1; shft[7]=nx+1; shftcode[1]=-1; shftcode[2]=1; shftcode[4]=-nx; shftcode[8]=nx; shftcode[16]=-nx-1; shftcode[32]=nx-1; shftcode[64]=-nx+1; shftcode[128]=nx+1; next: fifo4_lookreset(q); while ((ofs = fifo4_look(q))){ del=1; si=1; nsi=0; pcim=pim+ofs; pcflag=pflag+ofs; dep4=0; dep8=0; /* first make sure p is independent of all its simple neighbours */ for(i=0; i<4; i++){ /* first: scan 4-neighbours */ puc=pcflag+shft[i]; if (homotab[*puc]){ /* a simple neighbour */ del=0; si=0; ccode8=code8+8*i; for(j=0; j<4; j++){ /* 4 common 8-neighbours */ cfg = *pcflag & *ccode8++; cfg *= *puc & *ccode8; if (cfg){ /* common FG */ del=1; if (*(puc+shftcode[*ccode8])==0){ /* common non-simple FG */ si=1; break; } } ccode8++; } if (del==1){ /* check whether P has a 4^0 neighbour connected to a 4^0 neighbour of Q */ del=0; ccode4=code4+4*i; for(j=0; j<2; j++){ /* 2 4-neighbours of p 4-connected to a 4-neighbours of q */ cfg = *pcflag & *ccode4++; cfg += *puc & *ccode4; if (cfg==0){ /* P has a 4^0 neighbour connected to a 4^0 neighbour of Q */ del=1; break; } ccode4++; } } if (del==0){ /* dependent pixel */ if (si==1) goto next; /* dependent for IZ */ else dep4=1; } if (si==0) nsi=1; } /* a simple neighbour */ } /* first: scan 4-neighbours */ for(i=4; i<8; i++){ /* second: scan diagonal neighbours */ puc=pcflag+shft[i]; if (homotab[*puc]){ /* a simple neighbour */ del=0; si=0; ccode8=code8+32+4*(i-4); for(j=0; j<2; j++){ /* 2 common 8-neighbours */ cfg = *pcflag & *ccode8++; cfg *= *puc & *ccode8; if (cfg){ /* common FG */ del=1; if (*(puc+shftcode[*ccode8])==0){ /* common non-simple FG */ si=1; break; } } ccode8++; } if (del==0){ /* dependent pixel */ if (si==1) goto next; /* dependent for IZ */ else dep8=1; } if (si==0) nsi=1; } } /* line reached -> P is independent of ALL its simple neighbours */ /* in addition, if nsi==0, P is strictly independent of its simple neighbours */ nsn=0; if (nsi==1){ /* check whether P has a non-simple FG neighbour */ for (i=0; i<8; i++){ if ( (*pcflag & codei[i]) != 0){ if (*(pcflag + shftcode[*pcflag & codei[i]]) == 0){ nsn=1; break; } } } } if ( (nsn==0) && ((dep4==1) || (dep8==1)) ){ /* check whether P belongs to a simply CC of simple pixels */ if (*pcim == 0){ /* already processed */ printf("Already deleted\n"); goto next; } printf("check whether P belongs to a simply CC of simple pixels, ofs=%ld\n", ofs); fifo4_add(q3, pcim-pim); fifo4_add(q4, pcim-pim); *pcim=PIX_MAX; /* flag */ if ( (*pcflag & 138) == 0) cn = 1; else cn=0; if ( (*pcflag & 128) == 0) if ( (*pcflag & 64) ) cn--; val=0; while ((ofs2=fifo4_remove(q3))){ pcim2=pim+ofs2; for (j=0; j<8; j++){ if ( *(pcim2+shft[j]) == 1){ if ( *(pflag+ofs2+shft[j]) ){ fifo4_add(q3, pcim2+shft[j]-pim); fifo4_add(q4, pcim2+shft[j]-pim); *(pcim2+shft[j])=PIX_MAX; if ( (*(pflag+ofs2+shft[j]) & 138) == 0) cn++; if ( (*(pflag+ofs2+shft[j]) & 128) == 0) if ( (*(pflag+ofs2+shft[j]) & 64) ) cn--; } else{ /* non simple pixel in CC */ printf("NO\n"); val=1; fifo4_flush(q3); break; } } } } if (val==0){ printf("cn=%d\n", cn); } if (cn!=1) val=1; while ((ofs2=fifo4_remove(q4))){ *(pim+ofs2)=val; } } else if ( (nsi==0) || (nsn==0) ){ /* independent pixels (strictly or otherwise) */ *pcim=0; fifo4_add(q2, pcim-pim); count++; } /* else: dependent pixel */ } /* while */ while ((ofs = fifo4_remove(q))) /* reset codes */ *(pflag+ofs)=0; printf("count (number of independent simple pixels)=%d\n", count); /* return(1); */ count=0; while ((ofs = fifo4_remove(q2))){ for (i=0; i<8; i++){ /* scan neighbours of independent pixel */ pcim=pim+ofs+shft[i]; pcflag=pflag+ofs+shft[i]; if ( (*pcim!=PIX_MIN) && (*pcflag==0) ){ /* *pcim==255 for non-simple pixels */ h=*pcim; code=0; if (*(pcim-1)>=h) code=1; if (*(pcim+1)>=h) code|=2; if (*(pcim-nx)>=h) code|=4; if (*(pcim+nx)>=h) code|=8; if (*(pcim-nx-1)>=h) code|=16; if (*(pcim+nx-1)>=h) code|=32; if (*(pcim-nx+1)>=h) code|=64; if (*(pcim+nx+1)>=h) code|=128; if (homotab[code]){ fifo4_add(q, pcim-pim); /* insert offset position */ *pcflag=code; } /* CHECK: should never appear */ else if (code == 0){ /* isolated pixel (non-simple but deletable for IZ/WS) */ /* add in queue of ordered independent pixels */ *pcim=0; /* fifo4_add(q2, pcim-pim); CHECK THAT NOT NECESSARY!!! */ } } } } if (fifo4_empty(q)==0) goto next; free_fifo4(q); free_fifo4(q2); free_fifo4(q3); free_fifo4(q4); write_tiff(imflag, "/tmp/imflag.tif"); free_image(imflag); return NO_ERROR; } #include "g_undef.h" ERROR_TYPE oiiz(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return(generic_oiiz(im)); break; default: (void)sprintf(buf, "ERROR in oiiz(IMAGE *im): \ invalid ImDataType (MUST be UCHAR)\n"); errputstr(buf); return ERROR; } return ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/oiws.c000066400000000000000000000306561467232417700167200ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* First Tue Feb 24 2004 */ /** \addtogroup group_hmtsk * @{ */ #include #include #include "miallib.h" #include "fifo.h" #include "pqueue.h" #define BOX2_2D \ box[0]=box[1]=box[2]=box[3]=2; \ box[4]=box[5]=0 #include "g_def.h" ERROR_TYPE generic_oiws(IMAGE *im) { /* We propose to simulate an order independent flooding based on ordered indenpendent thinnings proceeding by increasing intensity levels. */ long int i, j, ofs; int del; /* Bool. variable ind. whether a pixel is deletable (1) or not (0) */ int si; /* Bool. variable ind. whether a pixel is strictly ind. (1) or not (0) of a given simple ngb */ int nsi; /* Bool. variable ind. whether a pixel is non-strictly ind. (1) or not (0) of all its simple ngb */ int cfg; /* Bool. variable ind. whether there is a common foreground neighbour */ int nsn=0; /* Bool. variable ind. whether there exists a pixel is non-simple ngb */ int code, codengb; int nx=GetImNx(im); long int npix=GetImNPix(im); int box[6]; int homotab[256] = { 0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,1,\ 1,0,0,0,1,0,1,1,1,1,1,0,1,1,0,0,1,0,0,0,1,0,1,0,1,0,1,0,1,1,0,1,0,\ 1,0,1,1,1,1,0,0,1,1,0,1,1,0,0,0,0,0,1,1,1,1,0,0,0,1,0,1,1,0,0,0,0,\ 0,0,1,0,1,0,0,1,1,0,1,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,1,0,1,0,\ 0,0,1,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,0,\ 0,0,1,1,1,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,0,0,1,0,0,0,\ 1,1,0,0,1,1,0,1,1,0,0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,0,0,0,0,0,0,0,0,\ 1,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0}; int code8[48] = { 16, 4, 4, 64, 32, 8, 8, 128,\ 4, 16, 64, 4, 8, 32, 128, 8,\ 1, 32, 16, 1, 2, 128, 64, 2,\ 32, 1, 1, 16, 128, 2, 2, 64,\ 4, 2, 1, 8,\ 8, 2, 1, 4,\ 2, 8, 4, 1,\ 2, 4, 8, 1}; int code4[16]= { 4, 4, 8, 8, 4, 4, 8, 8,\ 1, 1, 2, 2, 1, 1, 2, 2}; int codei[8] = {1, 2, 4, 8, 16, 32, 64, 128}; int shft[9], shftcode[129]; int *ccode8, *ccode4; IMAGE *imflag; /* image of flags */ UCHAR *pflag, *pcflag, *puc, *prmin, *pcrmin; PIX_TYPE *pim, *pcim, h, level=PIX_MIN, maxmin; FIFO4 *q, *q2, *q2bis, *aq, *qrmin; IMAGE *imrmin; struct pqueue *heap, *heapbis, *heaptmp; PQDATUM apqd[1]; struct node *pqd; int count=0; /* char fname[11]; */ /* create_lut(im); */ /* im->lut[46]=65535; */ /* im->lut[46+256]=0; */ /* im->lut[46+512]=0; */ /* im->lut[47]=0; */ /* im->lut[47+256]=65535; */ /* im->lut[47+512]=0; */ heap = (struct pqueue *)pqinit(NULL, 100); /* heap (priority queue) */ if (heap == NULL) return ERROR; heapbis = (struct pqueue *)pqinit(NULL, 100); /* heap (priority queue) */ if (heapbis == NULL) return ERROR; /* avoid border effects by setting border pixels to PIX_MAX */ BOX2_2D; /* width of 2 pixels */ generic_framebox(im, box, PIX_MAX); /* compute minima of input image */ imrmin = (IMAGE *)minima(im, 4); /* is of UCHAR type */ if (imrmin==NULL) return(ERROR); /* write_tiff(imrmin, "/tmp/imrmin0.tif"); */ BOX_2D; /* width of 1 pixels */ generic_framebox(im, box, PIX_MIN); BOX2_2D; /* width of 2 pixels */ generic_framebox(imrmin, box, 2); /* create flag image */ imflag = (IMAGE *)create_image(t_UCHAR,GetImNx(im), GetImNy(im), GetImNz(im)); if (imflag==NULL) return(ERROR); /* create a queue */ q = create_fifo4(npix/10L); if (q == NULL){ (void) sprintf(buf, "oiws(): not enough memory"); errputstr(buf); return ERROR; } aq = create_fifo4(npix/10L); if (aq == NULL){ (void) sprintf(buf, "oiws(): not enough memory"); errputstr(buf); return ERROR; } q2 = create_fifo4(npix/10L); if (q2 == NULL){ (void) sprintf(buf, "oiws(): not enough memory"); errputstr(buf); return ERROR; } q2bis = create_fifo4(npix/10L); if (q2bis == NULL){ (void) sprintf(buf, "oiws(): not enough memory"); errputstr(buf); return ERROR; } qrmin = create_fifo4(npix/10L); if (qrmin == NULL){ (void) sprintf(buf, "oiws(): not enough memory"); errputstr(buf); return ERROR; } shft[0]=-1; shft[1]=1; shft[2]=-nx; shft[3]=nx; shft[4]=-nx-1; shft[5]=nx-1; shft[6]=-nx+1; shft[7]=nx+1; shft[8]=0; shftcode[1]=-1; shftcode[2]=1; shftcode[4]=-nx; shftcode[8]=nx; shftcode[16]=-nx-1; shftcode[32]=nx-1; shftcode[64]=-nx+1; shftcode[128]=nx+1; /* initialise the queue with all simple pixels which neighbour a minimum */ pim =(PIX_TYPE *)GetImPtr(im); pcim =pim; prmin =(UCHAR *)GetImPtr(imrmin); pcrmin =prmin; pflag =(UCHAR *)GetImPtr(imflag); pcflag =pflag; for (i=0; i=h) code=1; if (*(pcim+shft[j]+1)>=h) code|=2; if (*(pcim+shft[j]-nx)>=h) code|=4; if (*(pcim+shft[j]+nx)>=h) code|=8; if (*(pcim+shft[j]-nx-1)>=h) code|=16; if (*(pcim+shft[j]+nx-1)>=h) code|=32; if (*(pcim+shft[j]-nx+1)>=h) code|=64; if (*(pcim+shft[j]+nx+1)>=h) code|=128; if (homotab[code] || (code==0)){ /* a simple pixel at level h */ count++; pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = h; pqd->offset= (long int)(pcim+shft[j]-pim); pqmininsert(heap, pqd); *(pcflag+shft[j])=code; } } } } } /* write_tiff(imrmin, "/tmp/imrmin.tif"); write_tiff(imflag, "/tmp/imflag"); */ printf("count (number of simple border pixels at init)=%d\n", count); count=0; if ( pqpeek(heap, apqd) != NULL){ level = (*apqd)->prio; } next: /* printf("level=%d\n", level); */ while ( pqpeek(heap, apqd) != NULL ){ h=(*apqd)->prio; if (h>level){ /* no more pixels at current level */ break; } pqminremove(heap, apqd); ofs=(*apqd)->offset; free((char*) *apqd); fifo4_add(aq, ofs); /* for reset later on */ del=1; si=1; nsi=0; pcim=pim+ofs; pcflag=pflag+ofs; if (*pcflag!=0){ /* non-isolated simple pixel */ /* first make sure p is independent of all its simple neighbours */ for(i=0; i<4; i++){ /* first: scan 4-neighbours */ puc=pcflag+shft[i]; if (homotab[*puc] && (*(pcim+shft[i])==h) ){ /* a simple neighbour at level h */ codengb=*puc; del=0; si=0; ccode8=code8+8*i; for(j=0; j<4; j++){ /* 4 common 8-neighbours */ cfg = *pcflag & *ccode8++; cfg *= *puc & *ccode8; if (cfg){ /* common FG */ del=1; if ( (*(puc+shftcode[*ccode8])==0) || \ (*(pcim+shft[i]+shftcode[*ccode8])>h) ){ /* common non-simple FG */ si=1; break; } } ccode8++; } if (del==1){ /* check whether P has a 4^0 neighbour connected to a 4^0 neighbour of Q */ del=0; ccode4=code4+4*i; for(j=0; j<2; j++){ /* 2 4-neighbours of p 4-connected to a 4-neighbours of q */ cfg = *pcflag & *ccode4++; cfg += *puc & *ccode4; if (cfg==0){ /* P has a 4^0 neighbour connected to a 4^0 neighbour of Q */ del=1; break; } ccode4++; } } if (del==0){ /* dependent pixel */ if ( ((*pcflag+codengb) == 3) || ((*pcflag+codengb) == 12) ){ nsi=0; goto skip; } goto next; } if (si==0) nsi=1; } /* a simple neighbour */ } /* first: scan 4-neighbours */ for(i=4; i<8; i++){ /* second: scan diagonal neighbours */ puc=pcflag+shft[i]; if (homotab[*puc] && (*(pcim+shft[i])==h)){ /* a simple neighbour at level h */ codengb=*puc; del=0; si=0; ccode8=code8+32+4*(i-4); for(j=0; j<2; j++){ /* 2 common 8-neighbours */ cfg = *pcflag & *ccode8++; cfg *= *puc & *ccode8; if (cfg){ /* common FG */ del=1; if ( (*(puc+shftcode[*ccode8])==0) || \ (*(pcim+shft[i]+shftcode[*ccode8]) > h) ){ /* common non-simple FG */ si=1; break; } } ccode8++; } if (del==0){ /* dependent pixel */ if ( ((*pcflag+codengb) == 96 ) || ((*pcflag+codengb) == 144) ){ nsi=0; goto skip; } goto next; } if (si==0) nsi=1; } } /* line reached -> P is independent of ALL its simple neighbours */ /* in addition, if nsi==0, P is strictly independent of its simple neighbours */ if (nsi==1){ /* check whether P has a non-simple FG neighbour */ nsn=0; for (i=0; i<8; i++){ if ( (*pcflag & codei[i]) != 0){ if ( (*(pcflag + shftcode[*pcflag & codei[i]]) == 0) || \ (*(pcim+shftcode[*pcflag & codei[i]]) > h)){ nsn=1; break; } } } } } skip: if ( (nsi==0) || (nsn==0) ){ /* independent pixels (strictly or otherwise) */ maxmin=PIX_MIN; for (j=0; j<8; j++){ if (*pcim > *(pcim+shft[j])){ maxmin=MAX(maxmin,*(pcim+shft[j])); } } fifo4_add(q2, pcim-pim); fifo4_add(q2bis, maxmin); } /* else: dependent pixel */ } /* while */ while ((ofs=fifo4_remove(aq))){ /* reset codes of pixels at current level */ *(pflag+ofs)=0; } while ((ofs=fifo4_remove(qrmin))){ /* reset flag in rmin of pixels at current level */ *(prmin+ofs)=0; } fifo4_lookreset(q2); while((ofs=fifo4_look(q2))){ *(pim+ofs)=fifo4_remove(q2bis); } /* printf("count (number of independent simple pixels)=%d (level = %d)\n", count, level); */ /* count=0; */ while ((ofs = fifo4_remove(q2))){ for (i=0; i<9; i++){ /* scan neighbours of independent pixel */ pcim=pim+ofs+shft[i]; pcflag=pflag+ofs+shft[i]; if ( (*pcflag==0) && (*(prmin+ofs+shft[i])==0) ){ /* (*pcim>=level) && */ *(prmin+ofs+shft[i])=2; fifo4_add(qrmin, ofs+shft[i]); /* for reset later on */ h=*pcim; code=0; if (*(pcim-1)>=h) code=1; if (*(pcim+1)>=h) code|=2; if (*(pcim-nx)>=h) code|=4; if (*(pcim+nx)>=h) code|=8; if (*(pcim-nx-1)>=h) code|=16; if (*(pcim+nx-1)>=h) code|=32; if (*(pcim-nx+1)>=h) code|=64; if (*(pcim+nx+1)>=h) code|=128; if (homotab[code] || (code==0) ){ /* a simple pixel at level h */ if (h>=level){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = h; pqd->offset= (long int)(pcim-pim); pqmininsert(heap, pqd); *pcflag=code; } else{ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = h; pqd->offset= (long int)(pcim-pim); pqmininsert(heapbis, pqd); *pcflag=code; } } } } } /* printf("count (number simple pixels at next iteration)=%d, level=%d\n", count, level); */ /* count=0; */ /* sprintf(fname, "im-%03d.tif", level); write_ColorMap_tiff(im, fname); */ if (pqpeek(heap, apqd)!=NULL){ level = (*apqd)->prio; goto next; } if (pqpeek(heapbis, apqd)!=NULL){ level = (*apqd)->prio; heaptmp=heap; heap=heapbis; heapbis=heaptmp; goto next; } free_fifo4(q); free_fifo4(aq); free_fifo4(q2); free_fifo4(q2bis); free_fifo4(qrmin); free_image(imflag); free_pq(heap); free_pq(heapbis); return NO_ERROR; } #include "g_undef.h" ERROR_TYPE oiws(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return(generic_oiws(im)); break; default: (void)sprintf(buf, "ERROR in oiws(IMAGE *im): \ invalid ImDataType\n"); errputstr(buf); return ERROR; } return ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/op.h000066400000000000000000000034301467232417700163500ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* op definitions */ #define ADD_op 0 /* arith */ #define SUB_op 1 #define MULT_op 2 #define DIV_op 3 #define INF_op 4 #define SUP_op 5 #define MASK_op 6 #define ADD_op_ovfl 7 #define SUB_op_ovfl 8 #define MULT_op_ovfl 9 #define AND_op 10 /* logical */ #define OR_op 11 #define XOR_op 12 #define CMP_op 13 #define ABSSUB_op 14 #define MASK_op2 15 #define SUBSWAP_op 16 #define SUBSWAP_op_ovfl 17 #define EQUAL_op 18 #define OVW_op 19 /* overwrite used for imput */ #define POW_op 20 #define NDI_op 21 /* normalised difference index */ #define SUBSWAPCST_op 22 /* change sign */ #define FirstBitOn_op 23 /* only retains first bit on */ #define NAND_op 24 /* logical */ #define ATAN_op 25 #define COS_op 26 #define SIN_op 27 jeolib-miallib-1.1.6/core/c/outeredge.c000066400000000000000000000344741467232417700177240ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2010-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* first 20100916 for building height measurement */ #include #include #include #include "miallib.h" #include "fifo.h" #ifdef OPENMP #include #endif /** \addtogroup group_label * @{ */ #include "u32_def.h" IMAGE *u32_outeredgelut(IMAGE *ilbl, IMAGE *iedgelbl) { /* extract the outer edge from labelled CCs given labelled internal boundaries of these CCs. The outer edges are defined as the connected component of internal boundary pixels connected to the infinite connected component of the background of the CC. It extracts the actual outer edges unless internal boundary matching outer edge is connected to internal boundaries coming from holes. This function is superseeded by outeredge() using Moore's contour tracing algorithm for actual outer edge extraction. Pierre Soille First 20100915 (for building footprint characterisation) */ G_TYPE *pg; IMAGE *lut; UINT32 *plut; PIX_TYPE *plbl, *pelbl, maxlbl; long int i; unsigned long int npix; /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); lut= (IMAGE *)create_image(t_UINT32, maxlbl+1, 1, 1); if (lut==NULL) return NULL; u32_blank(lut, 0); plut =(UINT32 *)GetImPtr(lut); plbl =(PIX_TYPE *)GetImPtr(ilbl); pelbl=(PIX_TYPE *)GetImPtr(iedgelbl); npix=GetImNPix(ilbl); for (i=0;i= maxcount) { // Close loop was 3: PiR: 2 for 8 and 1 for 4 ??? since we always start from upper left pixel (extreme pixel): NO counterexample in testouteredge.lsp on 20110928 //inside = trueval; // Since we are starting the search at were we first started we must set inside to true break; } } //IFMSB plbl[checkPosition]|=PIX_MSB; // mark pixel as border pout[checkPosition]=1; // mark pixel as border checkLocationNr = newCheckLocationNr;// Update which neighborhood position we should check next pos = checkPosition; counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited } else{ // Rotate clockwise in the neighborhood checkLocationNr = 1 + (checkLocationNr % graph); if(counter2 > graph){ // If counter2 is above 8 we have traced around the neighborhood and // therefore the border is a single black pixel and we can exit counter2 = 0; break; } else{ counter2 ++; } } } } } // } /* END of parallel region */ free_image(lut); return imout; } #undef MY_LUT_TYPE #undef t_MY_LUT_TYPE #include "u32_undef.h" IMAGE *outeredge(IMAGE *ilbl, int graph) { switch (GetImDataType(ilbl)){ case t_UINT32: return u32_outeredge(ilbl, graph); break; default: (void)sprintf(buf, "ERROR in outeredge(IMAGE *ilbl, int graph): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } } #include "u32_def.h" #define MY_LUT_TYPE UINT32 #define t_MY_LUT_TYPE t_UINT32 IMAGE *u32_outercontour(IMAGE *ilbl, int graph) { /* Processing based on contour representation: only points with change of direction are kept. Use MSB for flagging. assumes border is set to zero to avoid border overflow. Pierre Soille First 20100930 (for building footprint characterisation) based on Moore's contour tracing algorithm with Jacob's condition, see http://www.thebigblob.com/moore-neighbor-contour-tracing-algorithm-in-c/ by Erik Smistad (see local file moore_tracing.c) extended for label images as well as omp speed-up and graph. Additional image not actually necessary (coding in MSB is enough) but used to return an image with mask of outer edge pixels set to 1 (others to 0). http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html */ G_TYPE *pg; IMAGE *lut; MY_LUT_TYPE *plut; PIX_TYPE *plbl, maxlbl, lbl; IMAGE *imout; UCHAR *pout; int nx=GetImNx(ilbl); long int i, npix, pos; // openMP requires signed loop index int box[BOXELEM]; // Defines the neighborhood offset position from current position and the neighborhood // position we want to check next if we find a new border at checkLocationNr // 1 2 3 // 0 x 4 // 7 6 5 int neighborhood[8][2] = { {-1,7}, // red {-1-nx,7}, // green {-nx,1}, // blue {-nx+1,1}, // yellow {1,3}, // magenta {1+nx,3}, // cyan {nx,5}, // white {nx-1,5} // grey }; if (graph!=8) graph=4; if (graph==4){ // - 1 - // 0 x 2 // - 3 - neighborhood[0][0] = -1; // red neighborhood[0][1] = 4; neighborhood[1][0] = -nx; // green neighborhood[1][1] = 1; neighborhood[2][0] = 1; // blue neighborhood[2][1] = 2; neighborhood[3][0] = nx; // yellow neighborhood[3][1] = 3; } imout=(IMAGE *)create_image(t_UCHAR, GetImNx(ilbl), GetImNy(ilbl), 1); if (imout==NULL) return NULL; BOX_2D; u32_framebox(ilbl,box,0); /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); lut= (IMAGE *)create_image(t_MY_LUT_TYPE, maxlbl+1, 1, 1); if (lut==NULL){ free_image(imout); return NULL; } plut =(MY_LUT_TYPE *)GetImPtr(lut); plbl =(PIX_TYPE *)GetImPtr(ilbl); pout =(UCHAR *)GetImPtr(imout); npix =GetImNPix(ilbl); plut[0]=1; // dummy value to speed-up next loop /* first collect first point of each CC in an array for subsequent parallel processing */ for (i=0;i= 3) { // Close loop //inside = trueval; // Since we are starting the search at were we first started we must set inside to true break; } } pout[pos]=checkLocationNr; // direction of next border point // set to 9 if point of change of direction if (checkLocationNr!=prevCheckLocationNr){ pout[pos]=9; pout[checkPosition]=9; prevCheckLocationNr=checkLocationNr; } checkLocationNr = newCheckLocationNr;// Update which neighborhood position we should check next pos = checkPosition; counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited } else{ // Rotate clockwise in the neighborhood checkLocationNr = 1 + (checkLocationNr % graph); if(counter2 > graph){ // If counter2 is above 8 we have traced around the neighborhood and // therefore the border is a single black pixel and we can exit counter2 = 0; break; } else{ counter2 ++; } } } } } // } /* END of parallel region */ free_image(lut); return imout; } #undef MY_LUT_TYPE #undef t_MY_LUT_TYPE #include "u32_undef.h" IMAGE *outercontour(IMAGE *ilbl, int graph) { switch (GetImDataType(ilbl)){ case t_UINT32: return u32_outercontour(ilbl, graph); break; default: (void)sprintf(buf, "ERROR in outercontour(IMAGE *ilbl, int graph): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } } /*@}*/ jeolib-miallib-1.1.6/core/c/ovlmatrix.c000066400000000000000000000130341467232417700177530ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2012-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "miallib.h" #ifdef OPENMP #include #endif /** @addtogroup group_geom * @{ */ ERROR_TYPE ovlmatrix(IMAGE *matrix, IMAGE *maxg_array, char *odir) { /* Inputs: - symetric n x n overlap matrix - associcated maximum overlap level array indicating for each image the maximum degree of overlap encountered with gmax being the overall highest overlap level Note: both of type UCHAR (i.e., max 255 image overlapping simultaneously) Output: a series of text file in the form of ggg_sss_aaaaa.txt. The name indicates the overlap level (ggg), the order independent set (sss), the index to the anchor image of each independent image of this set (aaaaa). The content of each file is the index to the anchor image, followed by the list of indices of images intersecting it. DONE: - reduce the list to those images whose maximum overlap level is >= to the current overlap level. [20121201] TODO: - scan the images by decreasing order of overlap level to ensure a better distribution of the load Motivation: the lisp function in SGE_orderedBatchList.lsp is far too slow for large matrices such as those encountered for global HR coverages (10,000 x 10,000 matrices) First: 20141125 First running: 20141126 Author: Pierre Soille */ FILE *fp; IMAGE *imhst, *imrsum; HST1D_TYPE *prsum; UCHAR *pm, *pg; UCHAR *flagdep, *flagdone; unsigned int *idx; //char astr[]="/home/soillpi"; char fn[1024]; /* to hold odir/ggg_sss_aaaaa.txt */ int i, j, g=1, n, cnt_done, gmax=0; int flag, ois=1; /* ois: order independent set */ unsigned long int ofs; n=GetImNx(matrix); if ( (GetImNx(maxg_array)!= n) || \ (GetImDataType(matrix) != GetImDataType(maxg_array)) || \ (GetImDataType(matrix) != t_UCHAR)){ sprintf(buf, "error in ovlmatrix(): imcompatible input parameters\n"); errputstr(buf); return ERROR; } idx=(unsigned int *)calloc(n, sizeof(unsigned int)); pm=(UCHAR *)GetImPtr(matrix); pg=(UCHAR *)GetImPtr(maxg_array); for (i=0; igmax) gmax=pg[i]; /* sort the image indices in decreasing order of overlap value */ /* original order to start with */ /* Compute cumulated histogram */ imhst = histo1d(maxg_array); if (imhst==NULL){ free(idx); sprintf(buf, "error in ovlmatrix(): not enough memory\n"); errputstr(buf); return(ERROR); } imrsum = rsum(imhst); free_image(imhst); if (imrsum==NULL){ free(idx); return(ERROR); } prsum = (HST1D_TYPE *)GetImPtr(imrsum); for (i=0; i=2 */ // #pragma omp parallel for // private(g,cnt_done,ois,i,flagdone,flagdep,ofs,flag,j,fn,fp) for (g=2; g<=gmax; g++){ cnt_done=0; ois=1; while (cnt_done= g){ ofs=idx[i]*n; /* make sure independence condition is satisfied */ flag=1; for (j=0; j=g) ){ /* added 2nd condition 20141201 */ flagdep[j]=1; } } flagdone[idx[i]]=1; cnt_done++; /* create corresponding output list */ fp=fopen(fn,"wc"); fprintf(fp, "%05d\n", idx[i]); for (j=0; j=g) ) /* added 3rd condition 20141201 */ fprintf(fp, "%05d\n", idx[j]); } fclose(fp); } } else{ flagdone[idx[i]]=1; cnt_done++; } } } /* reset flagdep */ for (i=0; i. ***********************************************************************/ /* Given two partitions of the same image definition domain, determine for each segment of each partition, the segment of the other partition that it is most similar to. In the first test (20090225) the similarity measurement is defined as the ratio between the area of the intersection of the overlapping segments to the area of their union. by Pierre Soille */ #include #include #include #include "miallib.h" #include "fifo.h" #include "pqueue.h" /** \addtogroup group_seg * @{ */ /* printf("processing pixel %d, lbl1=%d, a1=%d, a2=%d, a2ia1=%d\n", \ */ /* i, pp1[i], a1, pla2[lbl2_crt], a2ia1); */ #include "uc_def.h" #define PIX_FLAG_TYPE UCHAR /* check for all uc_ when modifying! */ #define t_PIX_FLAG_TYPE 3 IMAGE **uc_PartitionSimilarity(IMAGE *part1, IMAGE *part2, int graph) { /* part1: labelled partition 1 part2: labelled partition 2 graph: connectivity used for creating the partitions */ unsigned long int i, ofs, npix; int nx, ny, nz, nmax; PIX_TYPE *pp1, *pp2, lbl1_crt, lbl2_crt; IMAGE *lut_s12, *lut_s21; /* holds similarities 1->2 and 2->1*/ float *ps12, scrt, s; IMAGE *lut_c12, *lut_c21; /* holds correspondences 1->2 and 2->1*/ PIX_TYPE *pc12; IMAGE *lut_area1, *lut_area2; /* holds areas of each segment */ HST1D_TYPE *pla1, *pla2, a1, a2ia1; IMAGE *im_flag; /* image to flag pixels already processed */ PIX_FLAG_TYPE *pflag; long int shft[27]; int n, k, box[6]; IMAGE **imap; /* holds all output arrays: correspondences and similarities */ FIFO4 *q; /* to find out current segment */ struct pqueue *pq; /* for statistics of intersection */ PQDATUM apqd[1]; struct node *pqd; /* area calculations */ lut_area1=histo1d(part1); if (lut_area1==NULL) return NULL; lut_area2=histo1d(part2); if (lut_area2==NULL){ free_image(lut_area1); return NULL; } /* memory allocation for similarity and correspondence arrays */ nmax=MAX(GetImNx(lut_area1),GetImNx(lut_area2)); lut_s12 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s12==NULL){ free_image(lut_area1); free_image(lut_area2); return NULL; } lut_s21 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); return NULL; } lut_c12 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c12==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); return NULL; } lut_c21 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); return NULL; } imap=(IMAGE **)calloc(sizeof(IMAGE *), 4); imap[0]=lut_c12; imap[1]=lut_c21; imap[2]=lut_s12; imap[3]=lut_s21; nx = GetImNx(part1); ny = GetImNy(part1); nz = GetImNz(part1); im_flag = (IMAGE *)create_image(t_PIX_FLAG_TYPE, nx, ny, nz); if (im_flag == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); } if (GetImNy(part1) == 1) {BOX_1D;} else if (GetImNz(part1) == 1) {BOX_2D;} else {BOX_3D;} if (set_seq_shift(nx, ny, nz, graph, shft) == ERROR){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); return NULL; } q = create_fifo4(100L); if (q == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); (void) sprintf(buf, "(): not enough memory"); errputstr(buf); return NULL; } pq = (struct pqueue *)pqinit(NULL, 100); /* priority queue */ if (pq == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); free_image(im_flag); free_fifo4(q); return NULL; } npix=GetImNPix(part1); for (n=0; n<2; n++){ /* process from 1 to 2 and 2 to 1 */ pflag=(PIX_FLAG_TYPE *)GetImPtr(im_flag); if (n==0){ pp1=(PIX_TYPE *)GetImPtr(part1); pp2=(PIX_TYPE *)GetImPtr(part2); pla1=(HST1D_TYPE *)GetImPtr(lut_area1); pla2=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s12); pc12=(PIX_TYPE *)GetImPtr(lut_c12); } else{ pp2=(PIX_TYPE *)GetImPtr(part1); pp1=(PIX_TYPE *)GetImPtr(part2); pla2=(HST1D_TYPE *)GetImPtr(lut_area1); pla1=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s21); pc12=(PIX_TYPE *)GetImPtr(lut_c21); generic_blank(im_flag, 0); /* reset im_flag */ } uc_framebox(im_flag, box, 1); /* 1 pixel thick border not processed */ for (i=0; iprio = pp2[i]; pqinsert(pq, pqd); /* propagate within current cc */ while ((ofs=fifo4_remove(q)) != (long int) NULL){ for (k = 0; kprio = pp2[ofs+shft[k]]; pqinsert(pq, pqd); } } } /* compute correspondence and similarity values */ a1=pla1[pp1[i]]; scrt=0.; a2ia1=0; /* area of cc2 falling in cc1 */ pqpeek(pq, apqd); lbl2_crt=(*apqd)->prio; while ( pqpeek(pq, apqd) != NULL ){ pqremove(pq, apqd); if ((*apqd)->prio!=lbl2_crt){ /* new intersecting cc found */ s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } a2ia1=0; lbl2_crt=(*apqd)->prio; } a2ia1++; free((char*) *apqd); } s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } } } } free_image(lut_area1); free_image(lut_area2); free_image(im_flag); free_fifo4(q); free_pq(pq); return(imap); } #undef PIX_FLAG_TYPE #undef t_PIX_FLAG_TYPE #include "uc_undef.h" #include "us_def.h" #define PIX_FLAG_TYPE UCHAR /* check for all uc_ when modifying! */ #define t_PIX_FLAG_TYPE 3 IMAGE **us_PartitionSimilarity(IMAGE *part1, IMAGE *part2, int graph) { /* part1: labelled partition 1 part2: labelled partition 2 graph: connectivity used for creating the partitions */ unsigned long int i, ofs, npix; int nx, ny, nz, nmax; PIX_TYPE *pp1, *pp2, lbl1_crt, lbl2_crt; IMAGE *lut_s12, *lut_s21; /* holds similarities 1->2 and 2->1*/ float *ps12, scrt, s; IMAGE *lut_c12, *lut_c21; /* holds correspondences 1->2 and 2->1*/ PIX_TYPE *pc12; IMAGE *lut_area1, *lut_area2; /* holds areas of each segment */ HST1D_TYPE *pla1, *pla2, a1, a2ia1; IMAGE *im_flag; /* image to flag pixels already processed */ PIX_FLAG_TYPE *pflag; long int shft[27]; int n, k, box[6]; IMAGE **imap; /* holds all output arrays: correspondences and similarities */ FIFO4 *q; /* to find out current segment */ struct pqueue *pq; /* for statistics of intersection */ PQDATUM apqd[1]; struct node *pqd; /* area calculations */ lut_area1=histo1d(part1); if (lut_area1==NULL) return NULL; lut_area2=histo1d(part2); if (lut_area2==NULL){ free_image(lut_area1); return NULL; } /* memory allocation for similarity and correspondence arrays */ nmax=MAX(GetImNx(lut_area1),GetImNx(lut_area2)); lut_s12 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s12==NULL){ free_image(lut_area1); free_image(lut_area2); return NULL; } lut_s21 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); return NULL; } lut_c12 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c12==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); return NULL; } lut_c21 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); return NULL; } imap=(IMAGE **)calloc(sizeof(IMAGE *), 4); imap[0]=lut_c12; imap[1]=lut_s12; imap[2]=lut_c21; imap[3]=lut_s21; nx = GetImNx(part1); ny = GetImNy(part1); nz = GetImNz(part1); im_flag = (IMAGE *)create_image(t_PIX_FLAG_TYPE, nx, ny, nz); if (im_flag == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); } if (GetImNy(part1) == 1) {BOX_1D;} else if (GetImNz(part1) == 1) {BOX_2D;} else {BOX_3D;} if (set_seq_shift(nx, ny, nz, graph, shft) == ERROR){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); return NULL; } q = create_fifo4(100L); if (q == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); (void) sprintf(buf, "(): not enough memory"); errputstr(buf); return NULL; } pq = (struct pqueue *)pqinit(NULL, 100); /* priority queue */ if (pq == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); free_image(im_flag); free_fifo4(q); return NULL; } npix=GetImNPix(part1); for (n=0; n<2; n++){ /* process from 1 to 2 and 2 to 1 */ pflag=(PIX_FLAG_TYPE *)GetImPtr(im_flag); if (n==0){ pp1=(PIX_TYPE *)GetImPtr(part1); pp2=(PIX_TYPE *)GetImPtr(part2); pla1=(HST1D_TYPE *)GetImPtr(lut_area1); pla2=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s12); pc12=(PIX_TYPE *)GetImPtr(lut_c12); } else{ pp2=(PIX_TYPE *)GetImPtr(part1); pp1=(PIX_TYPE *)GetImPtr(part2); pla2=(HST1D_TYPE *)GetImPtr(lut_area1); pla1=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s21); pc12=(PIX_TYPE *)GetImPtr(lut_c21); generic_blank(im_flag, 0); /* reset im_flag */ } uc_framebox(im_flag, box, 1); /* 1 pixel thick border not processed */ for (i=0; iprio = pp2[i]; pqinsert(pq, pqd); /* propagate within current cc */ while ((ofs=fifo4_remove(q)) != (long int) NULL){ for (k = 0; kprio = pp2[ofs+shft[k]]; pqinsert(pq, pqd); } } } /* compute correspondence and similarity values */ a1=pla1[pp1[i]]; scrt=0.; a2ia1=0; /* area of cc2 falling in cc1 */ pqpeek(pq, apqd); lbl2_crt=(*apqd)->prio; while ( pqpeek(pq, apqd) != NULL ){ pqremove(pq, apqd); if ((*apqd)->prio!=lbl2_crt){ /* new intersecting cc found */ s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } a2ia1=0; lbl2_crt=(*apqd)->prio; } a2ia1++; free((char*) *apqd); } s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } } } } free_image(lut_area1); free_image(lut_area2); free_image(im_flag); free_fifo4(q); free_pq(pq); return(imap); } #undef PIX_FLAG_TYPE #undef t_PIX_FLAG_TYPE #include "us_undef.h" #include "u32_def.h" #define PIX_FLAG_TYPE UCHAR /* check for all uc_ when modifying! */ #define t_PIX_FLAG_TYPE 3 IMAGE **u32_PartitionSimilarity(IMAGE *part1, IMAGE *part2, int graph) { /* part1: labelled partition 1 part2: labelled partition 2 graph: connectivity used for creating the partitions */ unsigned long int i, ofs, npix; int nx, ny, nz, nmax; PIX_TYPE *pp1, *pp2, lbl1_crt, lbl2_crt; IMAGE *lut_s12, *lut_s21; /* holds similarities 1->2 and 2->1*/ float *ps12, scrt, s; IMAGE *lut_c12, *lut_c21; /* holds correspondences 1->2 and 2->1*/ PIX_TYPE *pc12; IMAGE *lut_area1, *lut_area2; /* holds areas of each segment */ HST1D_TYPE *pla1, *pla2, a1, a2ia1; IMAGE *im_flag; /* image to flag pixels already processed */ PIX_FLAG_TYPE *pflag; long int shft[27]; int n, k, box[6]; IMAGE **imap; /* holds all output arrays: correspondences and similarities */ FIFO4 *q; /* to find out current segment */ struct pqueue *pq; /* for statistics of intersection */ PQDATUM apqd[1]; struct node *pqd; /* area calculations */ lut_area1=histo1d(part1); if (lut_area1==NULL) return NULL; lut_area2=histo1d(part2); if (lut_area2==NULL){ free_image(lut_area1); return NULL; } /* memory allocation for similarity and correspondence arrays */ nmax=MAX(GetImNx(lut_area1),GetImNx(lut_area2)); lut_s12 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s12==NULL){ free_image(lut_area1); free_image(lut_area2); return NULL; } lut_s21 = (IMAGE *)create_image(t_FLOAT, nmax, (int)1, (int)1); if (lut_s21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); return NULL; } lut_c12 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c12==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); return NULL; } lut_c21 = (IMAGE *)create_image(t_PIX_TYPE, nmax, (int)1, (int)1); if (lut_c21==NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); return NULL; } imap=(IMAGE **)calloc(sizeof(IMAGE *), 4); imap[0]=lut_c12; imap[1]=lut_s12; imap[2]=lut_c21; imap[3]=lut_s21; nx = GetImNx(part1); ny = GetImNy(part1); nz = GetImNz(part1); im_flag = (IMAGE *)create_image(t_PIX_FLAG_TYPE, nx, ny, nz); if (im_flag == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); } if (GetImNy(part1) == 1) {BOX_1D;} else if (GetImNz(part1) == 1) {BOX_2D;} else {BOX_3D;} if (set_seq_shift(nx, ny, nz, graph, shft) == ERROR){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); return NULL; } q = create_fifo4(100L); if (q == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free_image(im_flag); (void) sprintf(buf, "(): not enough memory"); errputstr(buf); return NULL; } pq = (struct pqueue *)pqinit(NULL, 100); /* priority queue */ if (pq == NULL){ free_image(lut_area1); free_image(lut_area2); free_image(lut_s12); free_image(lut_s21); free_image(lut_c12); free_image(lut_c21); free(imap); free_image(im_flag); free_fifo4(q); return NULL; } npix=GetImNPix(part1); for (n=0; n<2; n++){ /* process from 1 to 2 and 2 to 1 */ pflag=(PIX_FLAG_TYPE *)GetImPtr(im_flag); if (n==0){ pp1=(PIX_TYPE *)GetImPtr(part1); pp2=(PIX_TYPE *)GetImPtr(part2); pla1=(HST1D_TYPE *)GetImPtr(lut_area1); pla2=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s12); pc12=(PIX_TYPE *)GetImPtr(lut_c12); } else{ pp2=(PIX_TYPE *)GetImPtr(part1); pp1=(PIX_TYPE *)GetImPtr(part2); pla2=(HST1D_TYPE *)GetImPtr(lut_area1); pla1=(HST1D_TYPE *)GetImPtr(lut_area2); ps12=(float *)GetImPtr(lut_s21); pc12=(PIX_TYPE *)GetImPtr(lut_c21); generic_blank(im_flag, 0); /* reset im_flag */ } uc_framebox(im_flag, box, 1); /* 1 pixel thick border not processed */ for (i=0; iprio = pp2[i]; pqinsert(pq, pqd); /* propagate within current cc */ while ((ofs=fifo4_remove(q)) != (long int) NULL){ for (k = 0; kprio = pp2[ofs+shft[k]]; pqinsert(pq, pqd); } } } /* compute correspondence and similarity values */ a1=pla1[pp1[i]]; scrt=0.; a2ia1=0; /* area of cc2 falling in cc1 */ pqpeek(pq, apqd); lbl2_crt=(*apqd)->prio; while ( pqpeek(pq, apqd) != NULL ){ pqremove(pq, apqd); if ((*apqd)->prio!=lbl2_crt){ /* new intersecting cc found */ s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } a2ia1=0; lbl2_crt=(*apqd)->prio; } a2ia1++; free((char*) *apqd); } s=(float)a2ia1/(float)(a1+pla2[lbl2_crt]-a2ia1); if (scrt < s){ scrt=s; pc12[pp1[i]]=lbl2_crt; ps12[pp1[i]]=scrt; } } } } free_image(lut_area1); free_image(lut_area2); free_image(im_flag); free_fifo4(q); free_pq(pq); return(imap); } #undef PIX_FLAG_TYPE #undef t_PIX_FLAG_TYPE #include "u32_undef.h" /** * * * @param part1 an image holding a labelled partition * @param part2 another image holding a labelled partition (same size as part1) * @param graph integer for graph connectivity used for creating the partitions * * @return an image array holding similarity measures */ IMAGE **PartitionSimilarity(IMAGE *part1, IMAGE *part2, int graph) { /* can only be applied to unsigned data (pixel values considered as labels) */ /* check for possible errors */ if (szcompat(part1, part2) != NO_ERROR){ (void)sprintf(buf,"ERROR in **partition_similarity(): \ images of different size or type\n"); errputstr(buf); return(NULL); } switch (GetImDataType(part1)){ case t_UCHAR: return(uc_PartitionSimilarity(part1, part2, graph)); case t_USHORT: return(us_PartitionSimilarity(part1, part2, graph)); case t_UINT32: return(u32_PartitionSimilarity(part1, part2, graph)); default: (void)sprintf(buf,"**partition_similarity(): invalid pixel type must be unsigned\n"); errputstr(buf); break; } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/partorp.c000066400000000000000000000162541467232417700174240ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2006-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_seg * @{ */ #include "uc_def.h" ERROR_TYPE uc_IsPartitionEqual(IMAGE *im1, IMAGE *im2, int *result) { long int i, npix; PIX_TYPE *p1, *p2, maxi; G_TYPE *pg; int *lut; p1 = (PIX_TYPE *)GetImPtr(im1); p2 = (PIX_TYPE *)GetImPtr(im2); npix = GetImNPix(im1); /* get min & max values */ pg = min_max(im1); if (pg == NULL) return ERROR; maxi = pg[1].uc_val; free((char *)pg); /* create lut */ lut=(int *)calloc((size_t)maxi+1, sizeof(int)); if (lut == NULL){ (void)sprintf(buf,"uc_IsPartitionEqual(): not enough memory for lut!\n"); errputstr(buf); return ERROR; } for(i=0;i. ***********************************************************************/ /* starting from http://www.roboternetz.de/community/threads/57062-2D-Korrelation-Hilfe-bei-der-Implementierung-mit-FFT-%28FFTW-und-OpenCV%29 and correcting for several bugs related to scan order and wrong output generation Author: Pierre Soille First: 20120808 Last: 20120809 */ #include #include #include #include #include "config_miallib.h" //#ifdef OPENMP //#include //#endif #include #include "miallib.h" /** \addtogroup group_convolve * @{ */ #include "uc_def.h" IMAGE *uc_phase_correlation(IMAGE *im, IMAGE *im_template) { /* Phase-correlation method as first detailed in \cite{kuglin-hines75} That is, Inverse FFT of normalised product of FFT of im and complex conjugate of FFT of im_template. Still need to check: "If either G1 or G2 is 0 a some frequency, the corresponding phase factor is ambiguous and is therefore replace by zero" \cite{kuglin-hines75}. Question: divide by size or sqrt(size) or consider the square of the sum of modules? Author: Pierre Soille */ IMAGE *imout; double *pout; PIX_TYPE *pim=(PIX_TYPE *)GetImPtr(im); PIX_TYPE *pslave=(PIX_TYPE *)GetImPtr(im_template); fftw_complex *image_data, *image_fft_result, *templ_data, *templ_fft_result, *mul_result, *ifft_result; fftw_plan image_plan_forward_2d, templ_plan_forward_2d, plan_backward_2d; int i,j,k; int size_w = GetImNx(im); int size_h = GetImNy(im); long int size = size_w * size_h; double a,b,c,d,e, real, imag; /* create output image */ imout = (IMAGE *)create_image(t_DOUBLE, size_w, size_h, GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"phase_correlation(): not enough memory!\n"); errputstr(buf); return(imout); } pout=(double *)GetImPtr(imout); // data alloc //#ifdef OPENMP // int fftw_init_threads(void); //#endif image_data = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); image_fft_result = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); templ_data = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); templ_fft_result = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); mul_result = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); ifft_result = ( fftw_complex* ) fftw_malloc( sizeof( fftw_complex ) * size ); //#ifdef OPENMP // fftw_plan_with_nthreads(omp_get_max_threads()); //#endif image_plan_forward_2d = fftw_plan_dft_2d( size_w, size_h, image_data, image_fft_result, FFTW_FORWARD, FFTW_ESTIMATE ); //#ifdef OPENMP // fftw_plan_with_nthreads(omp_get_max_threads()); //#endif templ_plan_forward_2d = fftw_plan_dft_2d( size_w, size_h, templ_data, templ_fft_result, FFTW_FORWARD, FFTW_ESTIMATE ); //#ifdef OPENMP // fftw_plan_with_nthreads(omp_get_max_threads()); //#endif plan_backward_2d = fftw_plan_dft_2d( size_w, size_h, mul_result, ifft_result, FFTW_BACKWARD, FFTW_ESTIMATE ); /* CAUTION (from FFTW documentation): The multi-dimensional arrays passed to fftw_plan_dft etcetera are expected to be stored as a single contiguous block in row-major order (sometimes called ? order). Basically, this means that as you step through adjacent memory locations, the *first* dimension's index varies most *slowly* and the last dimension's index varies most quickly! */ /* load image data to FFTW input */ for( i = 0, k = 0 ; i < size_w ; i++ ){ for( j = 0 ; j < size_h ; j++, k++ ){ image_data[k][0] = pim[i+j*size_w]; image_data[k][1] = 0.0; } } /* load templ data to FFTW input */ for( i = 0, k = 0 ; i < size_w ; i++ ){ for( j = 0 ; j < size_h ; j++, k++ ){ templ_data[k][0] = pslave[i+j*size_w]; templ_data[k][1] = 0.0; } } fftw_execute(image_plan_forward_2d); fftw_execute(templ_plan_forward_2d); // komplex konjugiert von a mit b // et normalisation par le module du nombre complexe obtenu for( i = 0 ; i < size ; i++ ){ a = templ_fft_result[i][0]; b = templ_fft_result[i][1]; c = image_fft_result[i][0]; d = image_fft_result[i][1]; real = a*c+b*d; imag = a*d-b*c; e=sqrt(real*real+imag*imag); mul_result[i][0] = real/e; mul_result[i][1] = imag/e; } fftw_execute( plan_backward_2d ); /* load output with abs(F-1) */ for( i = 0, k = 0 ; i < size_w ; i++ ) { for( j = 0 ; j < size_h ; j++, k++ ) { pout[i+j*size_w] = sqrt(ifft_result[k][0]*ifft_result[k][0]+ifft_result[k][1]*ifft_result[k][1])/size; } } /* free memory */ fftw_destroy_plan( image_plan_forward_2d ); fftw_destroy_plan( templ_plan_forward_2d ); fftw_destroy_plan( plan_backward_2d ); fftw_free(image_data); fftw_free(image_fft_result); fftw_free(templ_data); fftw_free(templ_fft_result); fftw_free(ifft_result ); //#ifdef OPENMP // void fftw_cleanup_threads(void); //#endif return(imout); } #include "uc_undef.h" IMAGE *phase_correlation(IMAGE *im, IMAGE *im_template) { /* check for possible errors */ if (szcompat(im,im_template) != NO_ERROR){ (void)sprintf(buf,"ERROR in phase_correlation(): \ images of different type and/or sizes\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im)){ case t_UCHAR: return(uc_phase_correlation(im, im_template)); break; default: (void)sprintf(buf,"phase_correlation(im, im_template): invalid pixel type\n"); errputstr(buf); return(NULL); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/pointop.c000066400000000000000000003456551467232417700174370ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "op.h" #ifdef OPENMP #include #endif /** @defgroup group_pointop Point operations * Functions that are operating at the level of pixels without any neighbourhood information. * @{ */ /*************************************************************************/ /* im1[i] = im1[i] bit_op im2[i] */ ERROR_TYPE bitwise_op(IMAGE *im1, IMAGE *im2, int op) { long int *pim1, *pim2; mia_size_t i, nbyte, nword; nbyte = GetImNByte(im1); nword=nbyte/sizeof(long int); pim1 = (long int *)GetImPtr(im1); pim2 = (long int *)GetImPtr(im2); /* error checking */ if (GetImNByte(im2) != nbyte){ (void)sprintf(buf, "ERROR in bitwise_op(im1, im2, op): images do not have the same number of bytes\n"); errputstr(buf); return(ERROR); } /* here we go */ switch(op){ case AND_op: /* bitwise AND */ #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } p1[i] = (PIX_TYPE)test; } break; case SUB_op: #ifdef OPENMP #pragma omp parallel for private(test) reduction(+:ovfl) #endif for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } p1[i] = (PIX_TYPE)test; } break; case MULT_op_ovfl: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i p1[i]) p1[i] = p2[i]; break; case MASK_op: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i p2[i]) p1[i] = 2; else p1[i] = 0; } break; case EQUAL_op: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i *p1) *p1 = *p2; break; case MASK_op: for (i=0; i *p2) *p1 = 2; else *p1 = 0; } break; case EQUAL_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } p1[i] = (PIX_TYPE)test; #else p1[i] += cst #endif } break; case SUB_op: #ifdef OPENMP #pragma omp parallel for private(test) reduction(+:ovfl) #endif for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } p1[i] = (PIX_TYPE)test; #else p1[i] *= cst #endif } break; case MULT_op_ovfl: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i p1[i]) p1[i] = cst; break; case MASK_op: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i cst) p1[i] = 2; else p1[i] = 0; break; #if SIGNED case SUBSWAPCST_op: #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; #if SIGNED case SUBSWAPCST_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; #if SIGNED case SUBSWAPCST_op: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; #if SIGNED case SUBSWAPCST_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; #if SIGNED case SUBSWAPCST_op: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; case POW_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; #else *p1 += cst; #endif } break; case SUB_op: for (i=0; i PIX_MAX){ ovfl++; test = PIX_MAX; } *p1 = (PIX_TYPE)test; #else *p1 *= cst ; #endif } break; case MULT_op_ovfl: for (i=0; i *p1) *p1 = cst; break; case MASK_op: for (i=0; i cst) *p1 = 2; else *p1 = 0; break; #if SIGNED case SUBSWAPCST_op: for (i=0; i #endif ERROR_TYPE generic_imabs(IMAGE *im) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); for (i=0; i #endif ERROR_TYPE i32_imabs(IMAGE *im) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); for (i=0; i #endif ERROR_TYPE f_imabs(IMAGE *im) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); for (i=0; i #endif ERROR_TYPE d_imabs(IMAGE *im) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "s_def.h" ERROR_TYPE s_thresh(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "s_undef.h" #include "i32_def.h" ERROR_TYPE i32_thresh(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "i32_undef.h" #include "us_def.h" ERROR_TYPE us_thresh(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "us_undef.h" #include "u32_def.h" ERROR_TYPE u32_thresh(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "u32_undef.h" #include "f_def.h" ERROR_TYPE f_thresh(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "f_undef.h" #include "f_def.h" ERROR_TYPE f_threshstrict(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE bg, PIX_TYPE fg) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i t1 && p1[i] < t2) p1[i] = fg; else p1[i] = bg; } return(NO_ERROR); } #include "f_undef.h" ERROR_TYPE thresh(IMAGE *im, G_TYPE gt1, G_TYPE gt2, G_TYPE gbg, G_TYPE gfg) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_thresh(im, gt1.generic_val, gt2.generic_val, gbg.generic_val, gfg.generic_val)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_thresh(im, gt1.uc_val, gt2.uc_val, gbg.uc_val, gfg.uc_val)); break; #endif case t_USHORT: return(us_thresh(im, gt1.us_val, gt2.us_val, gbg.us_val, gfg.us_val)); break; case t_SHORT: return(s_thresh(im, gt1.s_val, gt2.s_val, gbg.s_val, gfg.s_val)); break; case t_UINT32: return(u32_thresh(im, gt1.u32_val, gt2.u32_val, gbg.u32_val, gfg.u32_val)); break; case t_INT32: return(i32_thresh(im, gt1.i32_val, gt2.i32_val, gbg.i32_val, gfg.i32_val)); break; case t_FLOAT: return(f_thresh(im, gt1.f_val, gt2.f_val, gbg.f_val, gfg.f_val)); break; #ifndef NO_d_IMAGE case t_DOUBLE: return(d_thresh(im, gt1.d_val, gt2.d_val, gbg.d_val, gfg.d_val)); break; #endif default: (void)sprintf(buf,"thresh(im, gt1, gt2, gbg, gfg): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /*************************************************************************/ /* im[i] = val if im[i] in [t1,t2] */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "s_def.h" ERROR_TYPE s_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "s_undef.h" #include "us_def.h" ERROR_TYPE us_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "i32_undef.h" #include "u32_def.h" ERROR_TYPE u32_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "u32_undef.h" #include "f_def.h" ERROR_TYPE f_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "f_undef.h" #include "d_def.h" ERROR_TYPE d_setlevel(IMAGE *im, PIX_TYPE t1, PIX_TYPE t2, PIX_TYPE val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i= t1 && p1[i] <= t2) p1[i] = val; } return(NO_ERROR); } #include "d_undef.h" ERROR_TYPE setlevel(IMAGE *im, G_TYPE gt1, G_TYPE gt2, G_TYPE gval) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_setlevel(im, gt1.generic_val, gt2.generic_val, gval.generic_val)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_setlevel(im, gt1.uc_val, gt2.uc_val, gval.uc_val)); break; #endif case t_USHORT: return(us_setlevel(im, gt1.us_val, gt2.us_val, gval.us_val)); break; case t_SHORT: return(s_setlevel(im, gt1.s_val, gt2.s_val, gval.s_val)); break; case t_UINT32: return(u32_setlevel(im, gt1.u32_val, gt2.u32_val, gval.u32_val)); break; case t_INT32: return(i32_setlevel(im, gt1.i32_val, gt2.i32_val, gval.i32_val)); break; case t_FLOAT: return(f_setlevel(im, gt1.f_val, gt2.f_val, gval.f_val)); break; case t_DOUBLE: return(d_setlevel(im, gt1.d_val, gt2.d_val, gval.d_val)); break; default: (void)sprintf(buf,"setlevel(im, gt1, gt2, gval): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } /*************************************************************************/ /* im[i] = im[i] mod val */ /* beware that modff is used for float types (no true generic function ! */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_modulo(IMAGE *im, int val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); #ifdef OPENMP #pragma omp parallel for #endif for (i=0; i val */ #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_shift(IMAGE *im, int val) { mia_size_t i, npix; PIX_TYPE *p1; p1 = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); if (val > 0){ for (i=0; i>= val; } else{ val = abs(val); for (i=0; i 0){ for (i=0; i>= val; } else{ val = abs(val); for (i=0; i 0){ for (i=0; i>= val; } else{ val = abs(val); for (i=0; i 0){ for (i=0; i>= val; } else{ val = abs(val); for (i=0; i. ***********************************************************************/ #include #include #include "pqueue.h" /* * pqinit: initialize the queue. * * Parameters: * * q Pointer to a priority queue, or NULL if the user * wishes to leave it to pqinit to allocate the queue. * * n Numer of queue items for which memory should be * preallocated, that is, the initial size of the * item array the queue uses. If you insert more than * n items to the queue, another n items will * be allocated automatically. * * Return values: * * non-NULL Priority queue has been initialized. * * NULL Insufficient memory. */ struct pqueue *pqinit(struct pqueue *q, int n) { struct pqueue *tmp = q; if (!q && !(q = malloc(sizeof(struct pqueue)))){ return NULL; } if (!(q->d = malloc(sizeof(PQDATUM) * n))){ if (!tmp) free(q); return NULL; } q->avail = q->step = n; q->size = 1; return q; } /* * pqinsert: insert an item into the queue. * * Parameters: * * q Pointer to a priority queue. * * d Datum to be inserted. * * Return values: * * 1 The item has been inserted. * * 0 The item could not be appended. Either the queue i * pointer provided was NULL, or the function was unable * to allocate the amount of memory needed for * the new item. */ int pqinsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; unsigned int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) < PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } int pqmaxinsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; unsigned int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) < PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } int pqmininsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; unsigned int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) > PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } /* * pqremove: remove the highest-ranking item from the queue. * * Parameters: * * p Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the queue item removed. * * Return values: * * non-NULL An item has been removed. The variable that d points * to now contains the datum associated with the item * in question. * * NULL No item could be removed. Either the queue pointer * provided was NULL, or the queue was empty. The chunk * of memory that d points to has not been modified. */ PQDATUM * pqremove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; unsigned int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) < PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) <= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } PQDATUM * pqmaxremove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; unsigned int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) < PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) <= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } PQDATUM * pqminremove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; unsigned int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) > PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) >= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } /* * pqpeek: access highest-ranking item without removing it. * * Parameters: * * q Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the highest-ranking item. * * Return values: * * non-NULL Success. The variable that d points to now contains * the datum associated with the highest-ranking item. * * NULL Failure. Either the queue pointer provided was NULL, * or the queue was empty. The chunk of memory that d * points to has not been modified. */ PQDATUM * pqpeek(struct pqueue *q, PQDATUM *d) { if (!q || q->size == 1) return NULL; *d = q->d[1]; return d; } /* * free memory allocated for a pqueue */ void free_pq(struct pqueue *q) { /* int i, count=0; */ #ifdef DEBUG printf("q->avail=%d\n", q->avail); printf("q->size=%d\n", q->size); #endif /* for (i=1; iavail; i++){ */ /* if (q->d[i] != NULL){ */ /* printf("unexpected non null datum in pq during freeing \n"); */ /* printf("q-d[%d]->prio=%d \n", i, q->d[i]->prio); */ /* //free(q->d[i]); */ /* count++; */ /* } */ /* } */ /* printf("%d datum were set to NULL in free_pq\n", count); */ free((void*) q->d); free((void*) q); } /* * free memory allocated for a pqueue */ void emergencyfree_pq(struct pqueue *q) { unsigned int i, count=0; printf("q->avail=%d\n", q->avail); printf("q->size=%d\n", q->size); for (i=1; isize; i++){ if (q->d[i] != NULL){ count++; free((char*) (q->d[i]) ); } } printf("%d datum were freed in free_pq\n", count); free((void *)q->d); free((void*)q); } /* * reset pqueue */ void reset_pq(struct pqueue *q) { unsigned int i; for (i=1; isize; i++){ if (q->d[i] != NULL){ free((char*) (q->d[i]) ); } } q->size=1; } jeolib-miallib-1.1.6/core/c/pqueue.h000066400000000000000000000033451467232417700172430ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #define PQDATUM struct node * #define PQPRIO(p) (p->prio) /* * Priority queue structure */ struct pqueue { unsigned int size, avail, step; PQDATUM *d; }; struct node { int prio; /* priority level */ int val; /* an associated integer value */ unsigned long int offset; /* offset to image origin */ int sof; /* offset to reference seed pixel (used in mssrgcore) */ }; extern struct pqueue * pqinit(struct pqueue *, int); extern int pqinsert(struct pqueue *, PQDATUM ); extern int pqmininsert(struct pqueue *, PQDATUM ); extern int pqmaxinsert(struct pqueue *, PQDATUM ); extern PQDATUM * pqremove(struct pqueue *, PQDATUM *); extern PQDATUM * pqminremove(struct pqueue *, PQDATUM *); extern PQDATUM * pqmaxremove(struct pqueue *, PQDATUM *); extern PQDATUM * pqpeek(struct pqueue *, PQDATUM *); extern void free_pq(struct pqueue *); extern void reset_pq(struct pqueue *); jeolib-miallib-1.1.6/core/c/pqueueExact.c000066400000000000000000000246121467232417700202230ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** pqueueExact.c - description ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #include #include #include "pqueueExact.h" /* * pqExactInit: initialize the queue. * * Parameters: * * q Pointer to a priority queue, or NULL if the user * wishes to leave it to pqinit to allocate the queue. * * n Numer of queue items for which memory should be * preallocated, that is, the initial size of the * item array the queue uses. If you insert more than * n items to the queue, another n items will * be allocated automatically. * * Return values: * * non-NULL Priority queue has been initialized. * * NULL Insufficient memory. */ struct pqueue *pqExactInit(struct pqueue *q, int n) { struct pqueue *tmp = q; if (!q && !(q = malloc(sizeof(struct pqueue)))){ return NULL; } if (!(q->d = malloc(sizeof(PQDATUM) * n))){ if (!tmp) free(q); return NULL; } q->avail = q->step = n; q->size = 1; return q; } /* * pqExactInsert: insert an item into the queue. * * Parameters: * * q Pointer to a priority queue. * * d Datum to be inserted. * * Return values: * * 1 The item has been inserted. * * 0 The item could not be appended. Either the queue i * pointer provided was NULL, or the function was unable * to allocate the amount of memory needed for * the new item. */ int pqExactInsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) < PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } /* * pqExactMaxInsert: insert an item into the queue. * * Parameters: * * q Pointer to a priority queue. * * d Datum to be inserted. * * Return values: * * 1 The item has been inserted. * * 0 The item could not be appended. Either the queue i * pointer provided was NULL, or the function was unable * to allocate the amount of memory needed for * the new item. */ int pqExactMaxInsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) < PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } /* * pqExactMinInsert: insert an item into the queue. * * Parameters: * * q Pointer to a priority queue. * * d Datum to be inserted. * * Return values: * * 1 The item has been inserted. * * 0 The item could not be appended. Either the queue i * pointer provided was NULL, or the function was unable * to allocate the amount of memory needed for * the new item. */ int pqExactMinInsert(struct pqueue *q, PQDATUM d) { PQDATUM *tmp; int i, newsize; if (!q) return 0; /* allocate more memory if necessary */ if (q->size >= q->avail){ newsize = q->size + q->step; if (!(tmp = realloc(q->d, sizeof(PQDATUM) * newsize))){ return 0; }; q->d = tmp; q->avail = newsize; } /* insert item */ i = q->size++; while (i > 1 && PQPRIO(q->d[i / 2]) > PQPRIO(d)){ q->d[i] = q->d[i / 2]; i /= 2; } q->d[i] = d; return 1; } /* * pqExcatRemove: remove the highest-ranking item from the queue. * * Parameters: * * p Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the queue item removed. * * Return values: * * non-NULL An item has been removed. The variable that d points * to now contains the datum associated with the item * in question. * * NULL No item could be removed. Either the queue pointer * provided was NULL, or the queue was empty. The chunk * of memory that d points to has not been modified. */ PQDATUM *pqExactRemove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) < PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) <= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } /* * pqExcatMaxRemove: remove an item from the queue. * * Parameters: * * p Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the queue item removed. * * Return values: * * non-NULL An item has been removed. The variable that d points * to now contains the datum associated with the item * in question. * * NULL No item could be removed. Either the queue pointer * provided was NULL, or the queue was empty. The chunk * of memory that d points to has not been modified. */ PQDATUM *pqExactMaxRemove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) < PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) <= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } /* * pqExcatMinRemove: remove an item from the queue. * * Parameters: * * p Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the queue item removed. * * Return values: * * non-NULL An item has been removed. The variable that d points * to now contains the datum associated with the item * in question. * * NULL No item could be removed. Either the queue pointer * provided was NULL, or the queue was empty. The chunk * of memory that d points to has not been modified. */ PQDATUM *pqExactMinRemove(struct pqueue *q, PQDATUM *d) { PQDATUM tmp; int i = 1, j; if (!q || q->size == 1) return NULL; *d = q->d[1]; tmp = q->d[--q->size]; while (i <= q->size / 2){ j = 2 * i; if (j < q->size && PQPRIO(q->d[j]) > PQPRIO(q->d[j + 1])){ j++; } if (PQPRIO(q->d[j]) >= PQPRIO(tmp)){ break; } q->d[i] = q->d[j]; i = j; } q->d[i] = tmp; return d; } /* * pqExactPeek: access highest-ranking item without removing it. * * Parameters: * * q Pointer to a priority queue. * * d Pointer to the PQDATUM variable that will hold the * datum corresponding to the highest-ranking item. * * Return values: * * non-NULL Success. The variable that d points to now contains * the datum associated with the highest-ranking item. * * NULL Failure. Either the queue pointer provided was NULL, * or the queue was empty. The chunk of memory that d * points to has not been modified. */ PQDATUM * pqExactPeek(struct pqueue *q, PQDATUM *d) { if (!q || q->size == 1) return NULL; *d = q->d[1]; return d; } /* * freeExact_pq: free memory allocated for a pqueue. * * Parameters: * * q Pointer to a priority queue. * * Return values: * * none */ void freeExact_pq(struct pqueue *q) { /* int i, count=0; */ /* for (i=0; isize; i++){ if (q->d[i] != NULL) free((char*) (q->d[i]) ); else count++; } printf("%d datum were set to NULL in free_pq\n", count); */ free(q->d); free(q); } /* * EmergencyFreeExact_pq: free memory allocated for a pqueue. * * Parameters: * * q Pointer to a priority queue. * * Return values: * * none */ void EmergencyFreeExact_pq(struct pqueue *q) { int i, count=0; printf("q->avail=%d\n", q->avail); printf("q->size=%d\n", q->size); for (i=1; isize; i++){ if (q->d[i] != NULL){ count++; free((char*) (q->d[i]) ); } } printf("%d datum were freed in free_pq\n", count); free(q->d); free(q); } jeolib-miallib-1.1.6/core/c/pqueueExact.h000066400000000000000000000041371467232417700202300ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** pqueueExact.h - description ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #ifndef init_pqueueExact #define init_pqueueExact #define PQDATUM struct node * #define PQPRIO(p) (p->prio) /* * Priority queue structure */ struct pqueue { int size, avail, step; PQDATUM *d; }; struct node { double prio; /* priority level */ long int val; /* an associated long integer value */ int offset; /* offset to image origin */ //int sof; /* offset to reference seed pixel (used in mssrgcore) */ }; extern struct pqueue * pqExactInit(struct pqueue *, int); extern int pqExactInsert(struct pqueue *, PQDATUM ); extern int pqExactMinInsert(struct pqueue *, PQDATUM ); extern int pqExactMaxInsert(struct pqueue *, PQDATUM ); extern PQDATUM * pqExactRemove(struct pqueue *, PQDATUM *); extern PQDATUM * pqExactMinRemove(struct pqueue *, PQDATUM *); extern PQDATUM * pqExactMaxRemove(struct pqueue *, PQDATUM *); extern PQDATUM * pqExactPeek(struct pqueue *, PQDATUM *); extern void freeExact_pq(struct pqueue *); #endif jeolib-miallib-1.1.6/core/c/projection.c000066400000000000000000000120601467232417700201000ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2005-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #if defined(LIBPROJ4) #define ACCEPT_USE_OF_DEPRECATED_PROJ_API_H #include #endif #ifdef OPENMP #include #endif #include "miallib.h" /** @defgroup group_proj Map projections * Functions dealing with map projections and corresponding pixel coordinate transformations. * @{ */ #if defined(LIBPROJ4) projXY proj(projXY idata, char *parms[], int n, int flag) { /* ** Author: Pierre Soille [EC-Joint Research Centre 2005] ** XY idata: coordinates of input (double type) representing either spheroidal or map coordinates ** char *parms[]: list of projection parameters ** n: number of parameters ** flag: 1 for forward projection, backward otherwise ** comment: wrapper for calling proj4 projection routines. Need to be adapted for PROJ > 6.0 */ projPJ *ref; projXY odata; odata.u=HUGE_VAL; odata.v=HUGE_VAL; if( ! (ref=pj_init(n, parms)) ){ return odata; } if (flag==1) odata = pj_fwd(idata, ref); else odata = pj_inv(idata, ref); pj_free((void *) ref); if (odata.u == HUGE_VAL){ if (flag==1){ sprintf(buf,"warning: pj_fwd() data conversion error\n"); errputstr(buf); } else{ sprintf(buf,"warning: pj_inv() data conversion error\n"); errputstr(buf); } } return odata; } IMAGE **cs2cs(double ulc_e, double ulc_n, int nx, int ny, double res, char *parmsi[], int ni, char *parmso[], int no) { /* ** Author: Pierre Soille [EC-Joint Research Centre 2005 (first 2005-08-12)] ** ulc_e/ulc_n: coordinates of input ULC (double type) representing either spheroidal or map coordinates ** char *parmsi[]: list of input projection parameters ** ni number of input parameters ** char *parmso[]: list of output projection parameters ** no number of input parameters ** imx: image to store x-coordinates of target image ** imy: image to store y-coordinates of target image ** res: resolution of target image ** comment: wrapper for calling proj4 projection routines. Need to be adapted for PROJ > 6.0 */ projPJ *fromProj, *toProj; int i,j; // int nx,ny; double x, y; double *pimx, *pimy, *z=NULL; IMAGE *imx=NULL, *imy=NULL, **imap=NULL; if( ! (fromProj=pj_init(ni, parmsi)) ){ /* init backward projection */ sprintf(buf,"error in cs2cs() error when calling backward pj_init()\n"); errputstr(buf); return NULL; } if( ! (toProj=pj_init(no, parmso)) ){ /* init forward projection */ sprintf(buf,"error in cs2cs() error when calling forward pj_init()\n"); errputstr(buf); return NULL; } imx=(IMAGE *)create_image(t_DOUBLE,nx,ny,1); if (imx==NULL){ sprintf(buf,"error: ics2cs() not enough memory\n"); errputstr(buf); return NULL; } imy=(IMAGE *)create_image(t_DOUBLE,nx,ny,1); if (imy==NULL){ free_image(imx); sprintf(buf,"error: ics2cs() not enough memory\n"); errputstr(buf); return NULL; } imap=(IMAGE **)calloc(2,sizeof(IMAGE *)); imap[0]=imx; imap[1]=imy; nx=GetImNx(imx); ny=GetImNy(imx); pimx=(double *)GetImPtr(imx); pimy=(double *)GetImPtr(imy); for(j=0,y=ulc_n; j. ***********************************************************************/ #include #include #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_label * @{ */ #include "uc_def.h" #define DST_TYPE UCHAR #define PIX_DST_MSB 0x80 #define PIX_DST 0x7F #define LBL_TYPE UINT32 ERROR_TYPE uc_propagate(IMAGE *lbl, IMAGE *dst, IMAGE **imap, int nc, int graph) { int c, k, tie=0, nties=0; unsigned long ofs, ofsk, npix=GetImNPix(imap[0]); long int d, dnext, dk, dkc, dcrt, dmax=UINT32_MAX; /* was double before 20111004 */ PIX_TYPE **pim; LBL_TYPE *pl; DST_TYPE *pd; long int shft[27]; FIFO4 *q; q = create_fifo4(16384L+GetImNx(dst)+GetImNy(dst)); if (q == NULL){ (void) sprintf(buf, "propagate(): not enough memory for fifo"); errputstr(buf); return ERROR; } set_shift(GetImNx(lbl), GetImNy(lbl), GetImNz(lbl), graph, shft); pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); for (c=0; cd){ */ else if (pd[ofsk]==dnext){ fifo4_add(q,(long int)ofsk); pd[ofsk]|=PIX_DST_MSB; } } if (tie==1) nties++; } fprintf(stderr, "number of ties in propagate= %d\n", nties); #ifdef OPENMP #pragma omp parallel for #endif for (ofs=0; ofsd){ */ else if (pd[ofsk]==dnext){ fifo4_add(q,(long int)ofsk); pd[ofsk]|=PIX_DST_MSB; } } if (tie==1) nties++; } fprintf(stderr, "number of ties in propagate= %d\n", nties); #ifdef OPENMP #pragma omp parallel for #endif for (ofs=0; ofs. ***********************************************************************/ #include #include #include #include "math.h" #include "miallib.h" #include "time.h" #include "pqueue.h" extern void tracelinecorrect(int, int, int, int , long int *, int *, int , int); /** @defgroup group_rank Rank filters * Functions dealing with rank filters. * @{ */ #include "uc_def.h" void uc_rank(im1, im2, nx, ny, nz, rank, box, shft, n) PIX_TYPE *im1, *im2; long int nx, ny, nz; int *box; long int *shft; long int n; int rank; { PIX_TYPE *p1, *p2; long int x, y, z; long int lstx, lsty, lstz; int i, trank; int hst[PIX_MAXP1]; /* histogram array */ int thcrt; double rindex = (double)rank/(n+1); lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ /* initialize histogram */ memset((void *) hst, 0, sizeof(int)*PIX_MAXP1); for (i=0; i= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } *p2++=i; p1++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } } #include "uc_undef.h" #include "us_def.h" void us_rank(im1, im2, nx, ny, nz, rank, box, shft, n) PIX_TYPE *im1, *im2; long int nx, ny, nz; int *box; long int *shft; long int n; int rank; { /* This function is dedicated to data types with more than 255 values or even with float data, contrary to the uc_rank function */ /* This function is still under development (can be improved): 1) ROI functionalitiescom should be activated 2) The use of both min- and max-priority queues should be considered depending on whether the rank is closer to the minimum or maximum rank. 3) Overlapping windows? */ PIX_TYPE *p1, *p2; long int x, y, z; long int lstx, lsty, lstz; struct pqueue *pq; PQDATUM *pqd; PQDATUM apqd[1]; int i; /* int outroi, thcrt; */ /* double rindex = (double)rank/(n+1); */ pq = (struct pqueue *)pqinit(NULL, n+1); /* priority queue */ /* if (pq == NULL) return ERROR; */ pqd = (PQDATUM *)malloc(sizeof(struct node *) * n); for (i=0;iprio = *(p1+shft[i]); pqmininsert(pq, pqd[i]); } /* calculate rank of current pixel */ /* thcrt= rindex*(n-outroi)+1; /\* necessary when there are pixels out of ROI *\/ */ for (i=0;iprio; pq->size=1; /* 'remove' all remaining elements */ p1++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } for (i=0;iprio = *(p1+shft[i]); pqmininsert(pq, pqd[i]); } /* calculate rank of current pixel */ /* thcrt= rindex*(n-outroi)+1; /\* necessary when there are pixels out of ROI *\/ */ for (i=0;iprio; pq->size=1; /* 'remove' all remaining elements */ p1++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } for (i=0;i= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } *pi++=i; /* calculate rank of remaining pixels */ pleft = p1; pright = p1+k; val = *(pi-1); /* output of previous (i.e. 1st) pixel */ for (i=1; i thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pi++=val; pleft++; pright++; } free(p1); } #include "uc_undef.h" #include "uc_def.h" ERROR_TYPE uc_linerank(PIX_TYPE *f, int ncol, int nlin, int dx, int dy, int k, int rank, int o) { /* ** f: image data as a 1D array ** ncol: number of image columns ** nlin: number of image lines ** dx: offset of SE along x from origin ** dy: offset of SE along y from origin ** k: extent of SE in pixels ** rank: ** o: */ PIX_TYPE *pi; long int *p, *ptmp; int *rlc; int inc, incx, incy; int pxf = 0, pyf = 0, nx, i, j, l, l1, l2, la, m; /* long int start; start = clock(); */ if (rank < 1 || rank > k){ (void)sprintf(buf,"Invalid rank value, must be in 1,...,k\n"); stdputstr(buf); return ERROR; } if (o < 0 || o > k-1){ (void)sprintf(buf,"Invalid origin, must be in 0,...,k-1\n"); stdputstr(buf); return ERROR; } if (dx == 0 && dy == 0){ (void)sprintf(buf,"Unknown slope: dx==dy==0"); stdputstr(buf); return ERROR; } if (dx<0){ dx = -dx; dy = -dy; } /* set coordinates of p array */ if (abs(dx) >= abs(dy)){ incx = 0; incy = 1; nx = ncol; l1 = (nx-1)*fabs((double)dy/dx)+0.5; l2 = nlin; if (dy > 0){ /* vert. translation */ pxf = nx-1; dx = -dx; dy = -dy; } } else{ incx = -1; incy = 0; nx = nlin; l1 = (nx-1)*fabs((double)dx/dy)+0.5; l2 = ncol; if (dy > 0){ /* horiz. translation */ pxf = (ncol-1); } else{ /* diag. translation */ pxf += (ncol-1); pyf = (nlin-1); } } p = (long int*)calloc(sizeof(long int),nx); rlc = (int*)calloc(sizeof(int),nx); pi = (PIX_TYPE *)calloc(sizeof(PIX_TYPE),nx); /* traceline(pxf, pyf, dx, dy, p, pb, rlc, ncol, nx, 1); */ tracelinecorrect(pxf, pyf, pxf+dx, pyf+dy, p, rlc, ncol, nx); /* process the whole image */ ptmp = p; inc = incx + ncol*incy; f -= inc; j = 0; la = (l2-l1) >= 0 ? l1:l2; for (i=0; i k*k){ (void)sprintf(buf,"Invalid rank value, must be in 1,...,k*k\n"); stdputstr(buf); return NULL; } if (ox < 0 || ox > k-1 || oy < 0 || oy > k-1){ (void)sprintf(buf,"Invalid origin, must be in SE\n"); stdputstr(buf); return NULL; } /* create output image */ imo = create_image((int)t_UCHAR, ncol, nlin, (int)1); if (imo==NULL){ (void)sprintf(buf,"Not enough memory in uc_squarerank()\n"); stdputstr(buf); return NULL; } po = (PIX_TYPE *)GetImPtr(imo); /* allocate and initialise shifts arrays */ nshft=k*k; shft=(int *)calloc(nshft, sizeof(int)); /* all pixels of SE */ for (y=0, i=0; y= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } *pocrt++=i; picrt++; /* process along line */ val=i; for (x=ox; x thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } free((void *) shft); free((void *) shfti); free((void *) shfto); return imo; } #include "uc_undef.h" #include "us_def.h" IMAGE *us_squarerank(PIX_TYPE *pi, int ncol, int nlin, int k, int rank, int ox, int oy) { /* ** pi: input image data as a 1D array ** ncol: number of image columns ** nlin: number of image lines ** k: width of square SE in pixels ** rank: ** ox: origin in x ** oy: origin in y ** returns: pointer to created image holding the filtered image ** comment: we assume that borders of appropriate width have been added ** to the image to handle border effects (value=PIX_MAX+1!!!) ** (c) by Pierre Soille. ALl rights reserved. This programme can only ** be obtained directly from its author. */ IMAGE *imo; PIX_TYPE *picrt, *po, *pocrt, val; int *shft, *shfti, *shfto, nshft; int x, y; int i, trank; int hst[PIX_MAX+1]; /* histogram array */ int thcrt; double rindex = (double)rank/(k*k+1); if (rank < 1 || rank > k*k){ (void)sprintf(buf,"Invalid rank value, must be in 1,...,k*k\n"); stdputstr(buf); return NULL; } if (ox < 0 || ox > k-1 || oy < 0 || oy > k-1){ (void)sprintf(buf,"Invalid origin, must be in SE\n"); stdputstr(buf); return NULL; } /* create output image */ imo = create_image((int)t_USHORT, ncol, nlin, (int)1); if (imo==NULL){ (void)sprintf(buf,"Not enough memory in us_squarerank()\n"); stdputstr(buf); return NULL; } po = (PIX_TYPE *)GetImPtr(imo); /* allocate and initialise shifts arrays */ nshft=k*k; shft=(int *)calloc(nshft, sizeof(int)); /* all pixels of SE */ for (y=0, i=0; y= thcrt){ trank-=hst[i]; /* trank contains number of pixels less than current rank */ break; } } *pocrt++=i; picrt++; /* process along line */ val=i; for (x=ox; x thcrt) do{ val -= 1; trank -= hst[val]; } while (trank > thcrt); else{ while (trank+hst[val] <= thcrt){ trank += hst[val]; val += 1; } } *pocrt=val; } } free((void *) shft); free((void *) shfti); free((void *) shfto); return imo; } #include "us_undef.h" IMAGE *squarerank(IMAGE *im, int k, int rank, int ox, int oy) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_squarerank((UCHAR *)GetImPtr(im), GetImNx(im), GetImNy(im), k, rank, ox, oy)); break; case t_USHORT: return(us_squarerank((USHORT *)GetImPtr(im), GetImNx(im), GetImNy(im), k, rank, ox, oy)); break; default: (void)sprintf(buf,"*squarerank(IMAGE *im, int k, int rank, int ox, int oy): invalid pixel type\n"); errputstr(buf); } return(NULL); } /*@}*/ jeolib-miallib-1.1.6/core/c/recons.c000066400000000000000000001167301467232417700172260ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2003-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "miallib.h" #include "fifo.h" #include "pqueue.h" // add_framebox/sub_framebox too much memory demanding in reconstruction // added flagged version on 2006-10-20 /** @defgroup group_geod Geodesic transformations * Functions dealing with image I/0. * @{ */ #include "uc_def.h" ERROR_TYPE uc_rdil(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** flag: if 0 then overwrite border else add border ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ generic_addframebox(mask, box, PIX_MIN); generic_addframebox(mark, box, PIX_MIN); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < *p_mk) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) < *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MIN(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_rdil(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ us_addframebox(mask, box, PIX_MIN); us_addframebox(mark, box, PIX_MIN); } else{ us_framebox(mask, box, PIX_MIN); us_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < *p_mk) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) < *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MIN(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ us_framebox(mask, box, PIX_MIN); us_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_rdil(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ i32_addframebox(mask, box, PIX_MIN); i32_addframebox(mark, box, PIX_MIN); } else{ i32_framebox(mask, box, PIX_MIN); i32_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk < *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im < *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < *p_mk) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ( (offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) < *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MIN(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ i32_framebox(mask, box, PIX_MIN); i32_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "i32_undef.h" #include "uc_def.h" ERROR_TYPE uc_rdilpdownhill(IMAGE *im_mark, IMAGE *im_mask, int n, int flag) { /* \cite{robinson-whelan2004} */ long int ix,iy,ox,oy,offset; int currentQ,currentP; int width,height,pixPerImg; int val1,val2,maxVal=0; int *istart,*irev,*ifwd; PIX_TYPE *mask, *marker; width=GetImNx(im_mask); height=GetImNy(im_mask); pixPerImg=width*height; mask=(PIX_TYPE *)GetImPtr(im_mask); marker=(PIX_TYPE *)GetImPtr(im_mark); for (offset = pixPerImg-1; offset >= 0; offset--) if (marker[offset] > maxVal) maxVal = marker[offset]; istart = (int*)malloc((maxVal+pixPerImg*2)*sizeof(int)); irev = istart+maxVal; ifwd = irev+pixPerImg; for (offset = -maxVal; offset < 0; offset++) irev[offset] = offset; for (offset = pixPerImg-1; offset >= 0; offset--){ if (marker[offset] > 0){ val1 = -marker[offset]; irev[offset] = val1; ifwd[offset] = irev[val1]; irev[val1] = offset; if (ifwd[offset] >= 0) irev[ifwd[offset]] = offset; } } for (currentQ = -maxVal; currentQ < 0; currentQ++){ currentP = irev[currentQ]; while (currentP >= 0){ irev[currentQ] = ifwd[currentP]; irev[currentP] = currentQ; ix = currentP%width; iy = currentP/width; for (oy = iy-1; oy <= iy+1; oy++){ for (ox = ix-1; ox <= ix+1; ox++){ if (ox >= 0 && oy >= 0 && ox < width && oy < height ){ offset = ox+oy*width; val1 = marker[offset]; val2 = marker[currentP]= 0) irev[ifwd[offset]] = irev[offset]; } marker[offset] = val2; irev[offset] = -val2; ifwd[offset] = irev[-val2]; irev[-val2] = offset; if (ifwd[offset] >= 0) irev[ifwd[offset]] = offset; } } } } currentP = irev[currentQ]; } } free(istart); return NO_ERROR; } #include "uc_undef.h" /* ** Geodesic dilation until idempotence. Overwriting algorithm. ** */ ERROR_TYPE rdil(IMAGE *mark, IMAGE *mask, int graph, int flag) { /* check for possible errors */ if (szcompat(mark, mask) != NO_ERROR){ (void)sprintf(buf,"ERROR in rdil(): incompatible input images\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(mark)){ case t_UCHAR: return(uc_rdil(mark, mask, graph, flag)); break; case t_USHORT: return(us_rdil(mark, mask, graph, flag)); break; case t_INT32: return(i32_rdil(mark, mask, graph, flag)); break; #ifndef NO_u32_IMAGE case t_UINT32: return(u32_rdil(mark, mask, graph, flag)); break; #endif default: (void)sprintf(buf,"rdil(): invalid pixel type\n"); errputstr(buf); } return(ERROR); } #include "uc_def.h" ERROR_TYPE uc_rero(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** flag: if 0 then overwrite border else add border ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rero(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ generic_addframebox(mask, box, PIX_MAX); generic_addframebox(mark, box, PIX_MAX); } else{ generic_framebox(mask, box, PIX_MAX); generic_framebox(mark, box, PIX_MAX); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) > *p_mk) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) > *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_rero(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rero(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ us_addframebox(mask, box, PIX_MAX); us_addframebox(mark, box, PIX_MAX); } else{ us_framebox(mask, box, PIX_MAX); us_framebox(mark, box, PIX_MAX); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) > *p_mk) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) > *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ us_framebox(mask, box, PIX_MIN); us_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "us_undef.h" #include "i32_def.h" ERROR_TYPE i32_rero(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2003-07-02 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** comment: The transformed image is written in the marker image. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rero(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ i32_addframebox(mask, box, PIX_MAX); i32_addframebox(mark, box, PIX_MAX); } else{ i32_framebox(mask, box, PIX_MAX); i32_framebox(mark, box, PIX_MAX); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ for (k = 0; k < nav; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ for (k = nav; k < n; k++){ if (*p_mk > *(p_mk + shft[k])) *p_mk = *(p_mk + shft[k]); } if (*p_im > *p_mk) *p_mk = *p_im; for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) > *p_mk) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ( (offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k = 0; k < n; k++){ if ( (*(p_mk+shft[k]) > *p_mk) && (*(p_im+shft[k]) != *(p_mk+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ i32_framebox(mask, box, PIX_MIN); i32_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "i32_undef.h" /* ** Reconstruciton by erosion using Vincent's algorithm [2003-07-02] ** */ ERROR_TYPE rero(IMAGE *mark, IMAGE *mask, int graph, int flag) { /* check for possible errors */ if (szcompat(mark, mask) != NO_ERROR){ (void)sprintf(buf,"ERROR in rero(): incompatible input images\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(mark)){ case t_UCHAR: return(uc_rero(mark, mask, graph, flag)); break; case t_USHORT: return(us_rero(mark, mask, graph, flag)); break; case t_INT32: return(i32_rero(mark, mask, graph, flag)); break; default: (void)sprintf(buf,"rero(): invalid pixel type\n"); errputstr(buf); } return(ERROR); } #include "uc_def.h" ERROR_TYPE uc_rerodilp(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2007-10-22 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** flag: if 0 then overwrite border else add border ** comment: The transformed image is written in the marker image. Version with a unique queue. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *q; /* create a queue */ q = create_fifo4(100L); if (q == NULL){ (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ generic_addframebox(mask, box, PIX_MIN); generic_addframebox(mark, box, PIX_MIN); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(q); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ if (*p_mk<*p_im){ for (k = 0; k < nav; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = 0; k < nav; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ if (*p_mk<*p_im){ for (k = nav; k < n; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = nav; k < n; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < MIN(*p_mk,*p_im)) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } else if ( (*(p_mk + shft[k]) > MAX(*p_mk,*p_im)) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ fifo4_add(q,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(q)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k=0; k= *(p_im)) && (*(p_mk+shft[k]) > *p_mk) && (*(p_mk+shft[k]) > *(p_im+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); fifo4_add(q,offset+shft[k]); } } } free_fifo4(q); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "uc_undef.h" #include "uc_def.h" ERROR_TYPE uc_rerodilp2q(IMAGE *mark, IMAGE *mask, int n, int flag) { /* ** author: P. Soille 2007-10-22 ** mark: Marker Image ** mask: Mask Image (mask <= mark) ** shft: array of offsets to neighbours ** n: number of neighbours ** flag: if 0 then overwrite border else add border ** comment: The transformed image is written in the marker image. Version with two queues, one for each reconstruction. */ long int shft[27]; int nav = n>>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); FIFO4 *qero, *qdil; /* create a queue */ qero = create_fifo4(100L); if (qero == NULL){ (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } qdil = create_fifo4(100L); if (qdil == NULL){ free_fifo4(qero); (void) sprintf(buf, "uc_rdil(): not enough memory"); errputstr(buf); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ generic_addframebox(mask, box, PIX_MIN); generic_addframebox(mark, box, PIX_MIN); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_fifo4(qero); free_fifo4(qdil); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ if (*p_mk<*p_im){ for (k = 0; k < nav; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = 0; k < nav; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ if (*p_mk<*p_im){ for (k = nav; k < n; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = nav; k < n; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < MIN(*p_mk,*p_im)) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ fifo4_add(qdil,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } if ( (*(p_mk + shft[k]) > MAX(*p_mk,*p_im)) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ fifo4_add(qero,(long int)(p_im-pmask)); /* offset to origin in queue */ break; } } } while ((offset=fifo4_remove(qero)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k=0; k *p_mk) && (*(p_mk+shft[k]) > *(p_im+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); fifo4_add(qero,offset+shft[k]); } } } while ((offset=fifo4_remove(qdil)) != (long int) NULL){ p_im=pmask+offset; p_mk=pmark+offset; for (k=0; k>1; register PIX_TYPE *p_mk, *p_im, *p_end, *pmask, *pmark; register int k; long int offset; int box[6]; long int nx = GetImNx(mark); long int ny = GetImNy(mark); long int nz = GetImNz(mark); struct pqueue *pqero, *pqdil; PQDATUM apqd[1]; struct node *pqd; /* create 2 priority queues */ pqero = (struct pqueue *)pqinit(NULL, 100); /* priority queue */ if (pqero == NULL) return ERROR; pqdil = (struct pqueue *)pqinit(NULL, 100); /* priority queue */ if (pqdil == NULL){ free_pq(pqero); return ERROR; } if (GetImNy(mark) == 1) {BOX_1D;} else if (GetImNz(mark) == 1) {BOX_2D;} else {BOX_3D;} if (flag){ generic_addframebox(mask, box, PIX_MIN); generic_addframebox(mark, box, PIX_MIN); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } nx = GetImNx(mark); ny = GetImNy(mark); nz = GetImNz(mark); /* take graph into account */ if (set_seq_shift(GetImNx(mark), GetImNy(mark), GetImNz(mark), n, shft) == ERROR){ free_pq(pqero); free_pq(pqdil); return ERROR; } /* Here we go! (Until stability) */ pmask=(PIX_TYPE *)GetImPtr(mask); pmark=(PIX_TYPE *)GetImPtr(mark); /* Forward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_first_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n) + 1; for (; p_mk < p_end; p_mk++, p_im++){ if (*p_mk<*p_im){ for (k = 0; k < nav; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = 0; k < nav; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } } /* Backward scan */ p_im = (PIX_TYPE *)GetImPtr(mask) + get_offset_last_pixel(nx, ny, nz, n); p_mk = (PIX_TYPE *)GetImPtr(mark) + get_offset_last_pixel(nx, ny, nz, n); p_end = (PIX_TYPE *)GetImPtr(mark) + get_offset_first_pixel(nx, ny, nz, n) - 1; for (; p_mk > p_end; --p_mk, --p_im){ if (*p_mk<*p_im){ for (k = nav; k < n; k++){ if (*p_mk < MIN(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MIN(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im < *p_mk) *p_mk = *p_im; } else if (*p_mk>*p_im){ for (k = nav; k < n; k++){ if (*p_mk > MAX(*(p_mk + shft[k]),*(p_im + shft[k])) ) // do not jump over *p_mk = MAX(*(p_mk + shft[k]),*(p_im + shft[k])); } if (*p_im > *p_mk) *p_mk = *p_im; } for (k = nav; k < n; k++){ if ( (*(p_mk + shft[k]) < MIN(*p_mk,*p_im)) && (*(p_mk + shft[k]) < *(p_im + shft[k])) ){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = *(p_mk + shft[k]); //pqd->val = val; pqd->offset= (long int)(p_im-pmask); pqmininsert(pqdil, pqd); break; } if ( (*(p_mk + shft[k]) > MAX(*p_mk,*p_im)) && (*(p_mk + shft[k]) > *(p_im + shft[k])) ){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = *(p_mk + shft[k]); //pqd->val = val; pqd->offset= (long int)(p_im-pmask); pqmaxinsert(pqero, pqd); break; } } } while ( pqpeek(pqero, apqd) != NULL ){ pqminremove(pqero, apqd); offset=(*apqd)->offset; p_im=pmask+offset; p_mk=pmark+offset; for (k=0; k *p_mk) && (*(p_mk+shft[k]) > *(p_im+shft[k])) ){ *(p_mk+shft[k])=MAX(*p_mk,*(p_im+shft[k])); pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = *(p_mk + shft[k]); //pqd->val = val; pqd->offset= offset+shft[k]; pqmininsert(pqero,pqd); } } free((char*) *apqd); } while ( pqpeek(pqdil, apqd) != NULL ){ pqmaxremove(pqdil, apqd); offset=(*apqd)->offset; p_im=pmask+offset; p_mk=pmark+offset; for (k=0; kprio = *(p_mk + shft[k]); //pqd->val = val; pqd->offset= offset+shft[k]; pqmaxinsert(pqdil,pqd); } } free((char*) *apqd); } free_pq(pqero); free_pq(pqdil); if (flag){ subframebox(mask, box); subframebox(mark, box); } else{ generic_framebox(mask, box, PIX_MIN); generic_framebox(mark, box, PIX_MIN); } return(NO_ERROR); } #include "uc_undef.h" #include "uc_def.h" ERROR_TYPE uc_rerodilpdownhill(IMAGE *im_mark, IMAGE *im_mask, int n, int flag) { /* based on rdildownhill, see also \cite{robinson-whelan2004} */ long int ix,iy,ox,oy,offset; long int currentQ,currentP; long int width,height,pixPerImg; int val1,val2,maxVal=0; int *istart,*irev,*ifwd; PIX_TYPE *mask, *marker; width=GetImNx(im_mask); height=GetImNy(im_mask); pixPerImg=width*height; mask=(PIX_TYPE *)GetImPtr(im_mask); marker=(PIX_TYPE *)GetImPtr(im_mark); for (offset = pixPerImg-1; offset >= 0; offset--) if (marker[offset] > maxVal) maxVal = marker[offset]; istart = (int*)malloc((maxVal+pixPerImg*2)*sizeof(int)); irev = istart+maxVal; ifwd = irev+pixPerImg; for (offset = -maxVal; offset < 0; offset++) irev[offset] = offset; for (offset = pixPerImg-1; offset >= 0; offset--){ if (marker[offset] > 0){ val1 = -marker[offset]; irev[offset] = val1; ifwd[offset] = irev[val1]; irev[val1] = offset; if (ifwd[offset] >= 0) irev[ifwd[offset]] = offset; } } for (currentQ = -maxVal; currentQ < 0; currentQ++){ currentP = irev[currentQ]; while (currentP >= 0){ irev[currentQ] = ifwd[currentP]; irev[currentP] = currentQ; ix = currentP%width; iy = currentP/width; for (oy = iy-1; oy <= iy+1; oy++){ for (ox = ix-1; ox <= ix+1; ox++){ if (ox >= 0 && oy >= 0 && ox < width && oy < height ){ offset = ox+oy*width; val1 = marker[offset]; val2 = marker[currentP]= 0) irev[ifwd[offset]] = irev[offset]; } marker[offset] = val2; irev[offset] = -val2; ifwd[offset] = irev[-val2]; irev[-val2] = offset; if (ifwd[offset] >= 0) irev[ifwd[offset]] = offset; } } } } currentP = irev[currentQ]; } } free(istart); return NO_ERROR; } #include "uc_undef.h" /* ** Self-dual reconstruction following alternative definition of Soille ** (no jump over). ** */ ERROR_TYPE rerodilp(IMAGE *mark, IMAGE *mask, int graph, int flag, int version) { /* check for possible errors */ if (szcompat(mark, mask) != NO_ERROR){ (void)sprintf(buf,"ERROR in rerodilp(): incompatible input images\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(mark)){ case t_UCHAR: switch (version){ case 1: return(uc_rerodilp(mark, mask, graph, flag)); break; case 2: return(uc_rerodilp2q(mark, mask, graph, flag)); break; case 3: return(uc_rerodilp2pq(mark, mask, graph, flag)); break; case 4: return(uc_rerodilpdownhill(mark, mask, graph, flag)); break; } break; default: (void)sprintf(buf,"rerodilp(): invalid pixel type\n"); errputstr(buf); } return(ERROR); } /*@}*/ jeolib-miallib-1.1.6/core/c/regionMean.c000066400000000000000000000253651467232417700200240ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** regionMean.c - description Region mean stores the mean value for each channel of a region. ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #include #include #include #include "regionMean.h" #include "miallib.h" /* * rminit: initialize region mean * * Parameters: * * rm Pointer to a regionMean * * nc Number of channels of the image to which the means shall be stored. * * * Return values: * * non-NULL regionMean has been initialized * * NULL Insufficient memory; */ struct regionMean *rmInit(struct regionMean *rm, int nc){ int i; float * mean; float * meanOriginal; //allocate space for channels if(!(mean=(float *) calloc(nc, sizeof(float)))){ return NULL; } if(!(meanOriginal=(float *) calloc(nc, sizeof(float)))){ return NULL; } //init the channels value with 0 for(i=0; imeanValue=mean; rm->meanValueOriginal=meanOriginal; rm->nc=nc; rm->count=0; rm->countOriginal=0; return rm; } /* * rmAddValue: add value (from each channel) to mean values of region * * Parameters: * * rm Pointer to a regionMean * * imap Array of IMAGE * * offset offset to values in IMAGE which shall be added. * * * Return values: * * 1 The values has been added * * 0 The values could not been added. The pointer rm or imap was NULL. */ #include "uc_def.h" int uc_rmAddValue(struct regionMean *rm, IMAGE **imap, long int offset){ int i, n; long int crtCount; float * mean, crtMean, newMean,crtValue; PIX_TYPE *value; if(!rm || !imap) return 0; mean= rm->meanValue; n = rm->nc; crtCount = rm->count; for(i=0; icount=crtCount; return 1; } #include "uc_undef.h" #include "us_def.h" int us_rmAddValue(struct regionMean *rm, IMAGE **imap, long int offset){ int i, n; long int crtCount; float * mean, crtMean, newMean,crtValue; PIX_TYPE *value; if(!rm || !imap) return 0; mean= rm->meanValue; n = rm->nc; crtCount = rm->count; for(i=0; icount=crtCount; return 1; } #include "us_undef.h" int rmAddValue(struct regionMean *rm, IMAGE **imap, long int offset){ switch(GetImDataType(imap[0])){ case t_UCHAR: return(uc_rmAddValue(rm, imap, offset)); break; case t_USHORT: return(us_rmAddValue(rm, imap, offset)); break; default: (void)sprintf(buf,"rmAddValue(): invalid pixel type\n"); errputstr(buf); } return 0; } /* * rmGetDistanceToRM: calculates the distance between two pixels. * The distance is the square root of the sum of (x2-x1)(x2-x1) * for each channel. For the calculation, all pixels in the mean * are considered. * * Parameters: * * rm Pointer to a regionMean * * imap Array of IMAGE * * offset offset to a pixel in IMAGE. * * * Return values: * * >=0 Distance * * -1 The Distance could not been calculated. The pointer rm or imap was NULL. */ #include "uc_def.h" double uc_rmGetDistanceToRM(struct regionMean *rm, IMAGE **imap, long int offset){ int i, n; float * mean; PIX_TYPE *value; double tmp, distance=0; if(!rm || !imap) return -1; mean= rm->meanValue; n = rm->nc; for(i=0; imeanValue; n = rm->nc; for(i=0; imeanValueOriginal; n = rm->nc; crtCount = rm->countOriginal; for(i=0; icountOriginal=crtCount; uc_rmAddValue(rm, imap, offset); return 1; } #include "uc_undef.h" #include "us_def.h" int us_rmAddValueOriginal(struct regionMean *rm, IMAGE **imap, long int offset){ int i, n; long int crtCount; float * mean, crtMean, newMean,crtValue; PIX_TYPE *value; if(!rm || !imap) return 0; mean= rm->meanValueOriginal; n = rm->nc; crtCount = rm->countOriginal; for(i=0; icountOriginal=crtCount; us_rmAddValue(rm, imap, offset); return 1; } #include "us_undef.h" /* * rmGetDistanceToOriginalRM: calculates the distance between two pixels. * The distance is the square root of the sum of (x2-x1)(x2-x1) * for each channel. For the caluclation, only the pixels belonging * to the original seeds are considered * * Parameters: * * rm Pointer to a regionMean * * imap Array of IMAGE * * offset offset to a pixel in IMAGE. * * * Return values: * * >=0 Distance * * -1 The Distance could not been calculated. The pointer rm or imap was NULL. */ #include "uc_def.h" double uc_rmGetDistanceToOriginalRM(struct regionMean *rm, IMAGE **imap, long int offset) { int i, n; float * mean; PIX_TYPE *value; double tmp, distance=0; if(!rm || !imap) return -1; mean= rm->meanValueOriginal; n = rm->nc; for(i=0; imeanValueOriginal; n = rm->nc; for(i=0; i 0) * or darker (coefficient <0) than the region. * * Parameters: * * rm Pointer to a regionMean * * imap Array of IMAGE * * offset offset to a pixel in IMAGE. * * * Return values: * * >0 Pixel is brighter than region * * =0 Pixel is equal to region * * <0 Pixel is darker */ #include "uc_def.h" double uc_rmGetContrastCoefficient(struct regionMean *rm, IMAGE **imap, long int offset){ int i,n; float * mean = rm->meanValue; PIX_TYPE * value; double contrast=0; n = rm->nc; for(i=0; imeanValue; PIX_TYPE * value; double contrast=0; n = rm->nc; for(i=0; inc, i; float * mean=rm->meanValue; float * meanOriginal=rm->meanValueOriginal; //init the channels value with 0 for(i=0; icount=0; rm->countOriginal=0; return; } /* * freeRegionMean: free region Mean * * Parameters: * * rm Pointer to a regionMean * * * Return values: * * none; * */ void freeRegionMean(struct regionMean * rm) { free(rm->meanValue); free(rm->meanValueOriginal); } jeolib-miallib-1.1.6/core/c/regionMean.h000066400000000000000000000046671467232417700200330ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** regionMean.h - description ------------------- begin : Thu Apr 22 2004 ***************************************************************************/ #ifndef init_regionMean #define init_regionMean #include "miallib.h" struct regionMean { float * meanValueOriginal; float * meanValue; int nc; //number of channels long int count; //number values stored in meanValues long int countOriginal; // numbers of values stored in meanValueOriginal }; struct regionMean * rmInit(struct regionMean *rm, int nc); int rmAddValue(struct regionMean * rm, IMAGE **imap, long int offset); int uc_rmAddValue(struct regionMean * rm, IMAGE **imap, long int offset); int rmAddValueOriginal(struct regionMean * rm, IMAGE **imap, long int offset); int uc_rmAddValueOriginal(struct regionMean * rm, IMAGE **imap, long int offset); double rmGetDistanceToRM(struct regionMean * rm, IMAGE **imap, long int offset); double uc_rmGetDistanceToRM(struct regionMean * rm, IMAGE **imap, long int offset); double rmGetDistanceToOriginalRM(struct regionMean * rm, IMAGE **imap, long int offset); double uc_rmGetDistanceToOriginalRM(struct regionMean * rm, IMAGE **imap, long int offset); double rmGetContrastCoefficient(struct regionMean * rm, IMAGE **imap, long int offset); double uc_rmGetContrastCoefficient(struct regionMean * rm, IMAGE **imap, long int offset); void clearRegionMean(struct regionMean * rm); void freeRegionMean(struct regionMean * rm); #endif jeolib-miallib-1.1.6/core/c/registration.c000066400000000000000000000350551467232417700204470ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2006-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include #include "miallib.h" /** \addtogroup group_stat * @{ */ /* Sequential similarity detection algorithm (ssda) from author = {Barnea, D. and Silverman, H.}, title = {A class of algorithms for fast digital registration}, journal = {IEEE Transactions on Computers}, year = {1972}, volume = {C-21}, pages = {179-186}, ** First: 2006-11-25 ** Pierre Soille */ #include "uc_def.h" IMAGE *uc_ssda(IMAGE *imin, IMAGE *imt, int xi, int yi, int w) { IMAGE *imout, *iml; PIX_TYPE *pi, *pl, *plend, *pt; float *po, e; long int *shft, *shftcrt; int u, ustart, v, vstart; int n=GetImNPix(imt); int i, k; int nxi=GetImNx(imin); int nyi=GetImNy(imin); int nxt=GetImNx(imt); int nyt=GetImNy(imt); int wd2=(int)w/2, nxtd2=(int)nxt/2, nytd2=(int)nyt/2; float mui, mut=0.0; /* check w leads to windows falling in imin */ if( (xi-(wd2+nxtd2)<0) || (xi+(wd2+nxtd2)>=nxi) || \ (yi-(wd2+nytd2)<0) || (yi+(wd2+nytd2)>=nyi) ){ (void)sprintf(buf,"*ssda(): lead to a window falling outside imin defintion domain\n"); errputstr(buf); return NULL; } /* create and initialise shift array */ shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; shftcrt=shft; for (v=0;v0;i--) mut+=*pt++; mut/=n; pt=(PIX_TYPE *)GetImPtr(imt); /* here we go */ plend=(PIX_TYPE *)GetImPtr(iml)+n; vstart=yi-(int)(w/2)-nytd2; ustart=xi-(int)(w/2)-nxtd2; for(v=0;v=nxi) || \ (yi-(wd2+nytd2)<0) || (yi+(wd2+nytd2)>=nyi) ){ (void)sprintf(buf,"*ssda(): lead to a window falling outside imin defintion domain\n"); errputstr(buf); return NULL; } /* create and initialise shift array */ shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; shftcrt=shft; for (v=0;v0;i--) mut+=*pt++; mut/=n; pt=(PIX_TYPE *)GetImPtr(imt); /* here we go */ plend=(PIX_TYPE *)GetImPtr(iml)+n; vstart=yi-(int)(w/2)-nytd2; ustart=xi-(int)(w/2)-nxtd2; for(v=0;v=nxi) || \ (yi-(wd2+nytd2)<0) || (yi+(wd2+nytd2)>=nyi) ){ (void)sprintf(buf,"*ncc(): lead to a window falling outside imin defintion domain\n"); errputstr(buf); return NULL; } /* create and initialise shift array */ shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; shftcrt=shft; for (v=0;v0;i--) mut+=*pt++; mut/=n; /* compute variance of template */ pt=(PIX_TYPE *)GetImPtr(imt); for(i=n;i>0;i--){ diff=*pt++-mut; vart+=(diff*diff); } /* create sum tables */ s=(INT32 *)GetImPtr(sim); ssq=(UINT64 *)GetImPtr(ssqim); // iminfo(sim); // iminfo(ssqim); /* here we go */ pt=(PIX_TYPE *)GetImPtr(imt); vstart=yi-(int)(w/2)-nytd2; ustart=xi-(int)(w/2)-nxtd2; #ifdef OPENMP #pragma omp parallel for private(pi,u,mui,vari,numer,k,denom) #endif for(v=0;v=nxi) || \ (yi-(wd2+nytd2)<0) || (yi+(wd2+nytd2)>=nyi) ){ (void)sprintf(buf,"*ncc(): lead to a window falling outside imin defintion domain\n"); errputstr(buf); return NULL; } /* create and initialise shift array */ shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; shftcrt=shft; for (v=0;v0;i--) mut+=*pt++; mut/=n; /* compute variance of template */ pt=(PIX_TYPE *)GetImPtr(imt); for(i=n;i>0;i--){ diff=*pt++-mut; vart+=(diff*diff); } pt=(PIX_TYPE *)GetImPtr(imt); /* here we go */ plend=(PIX_TYPE *)GetImPtr(iml)+n; vstart=yi-(int)(w/2)-nytd2; ustart=xi-(int)(w/2)-nxtd2; for(v=0;v=nxi) || \ (yi-(wd2+nytd2)<0) || (yi+(wd2+nytd2)>=nyi) ){ (void)sprintf(buf,"*ncc(): lead to a window falling outside imin defintion domain\n"); errputstr(buf); return NULL; } /* create and initialise shift array */ shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; shftcrt=shft; for (v=0;v0;i--) mut+=*pt++; mut/=n; /* compute variance of template */ pt=(PIX_TYPE *)GetImPtr(imt); for(i=n;i>0;i--){ diff=*pt++-mut; vart+=(diff*diff); } pt=(PIX_TYPE *)GetImPtr(imt); /* here we go */ plend=(PIX_TYPE *)GetImPtr(iml)+n; vstart=yi-(int)(w/2)-nytd2; ustart=xi-(int)(w/2)-nxtd2; for(v=0;v. ***********************************************************************/ #include #include /* From http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/doxygen/loon/html/novas_8c.html#a4004871 Accessed on 2005-08-09 This function will compute the Julian date for a given calendar date (year, month, day, hour). REFERENCES: Fliegel & Van Flandern, Comm. of the ACM, Vol. 11, No. 10, October 1968, p. 657. INPUT ARGUMENTS: year (short int) Year. month (short int) Month number. day (short int) Day-of-month. hour (double) Hour-of-day. OUTPUT ARGUMENTS: None. RETURNED VALUE: (double) Julian date. GLOBALS USED: None. FUNCTIONS CALLED: None. VER./DATE/ PROGRAMMER: V1.0/06-98/JAB (USNO/AA) NOTES: 1. This function is the "C" version of Fortran NOVAS routine 'juldat'. 2. This function makes no checks for a valid input calendar date. ------------------------------------------------------------------------ */ double julian_date(short int year, short int month, short int day, double hour) { long int jd12h; double tjd; jd12h = (long) day - 32075L + 1461L * ((long) year + 4800L + ((long) month - 14L) / 12L) / 4L + 367L * ((long) month - 2L - ((long) month - 14L) / 12L * 12L) / 12L - 3L * (((long) year + 4900L + ((long) month - 14L) / 12L) / 100L) / 4L; tjd = (double) jd12h - 0.5 + hour / 24.0; return (tjd); } jeolib-miallib-1.1.6/core/c/rminmax.c000066400000000000000000000126371467232417700174110ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_geod * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_minima(IMAGE *im1, int graph) { IMAGE *im2; int box[6]; long int i, k, nelem, shft[27]; PIX_TYPE *p, *pp, *pim1 = (PIX_TYPE *)GetImPtr(im1); UCHAR *pim2; FIFO4 *q; im2 = create_image(t_UCHAR, GetImNx(im1), GetImNy(im1), GetImNz(im1)); if (im2 == NULL) return NULL; q = create_fifo4(GetImNx(im1)+GetImNy(im1)); if (q == NULL){ free_image(im2); return NULL; } /* set to 1 im2 */ generic_blank(im2, 1); /* draw frames */ if ( GetImNz(im1) > 1) {BOX_3D;} else {BOX_2D;} generic_framebox(im1, box, PIX_MAX); uc_framebox(im2, box, 0); /* set shift array */ set_seq_shift(GetImNx(im1), GetImNy(im1), GetImNz(im1), graph, shft); /* Here we go */ nelem = GetImNPix(im1); pim2=(UCHAR *)GetImPtr(im2); for (i=0; i 1) {BOX_3D;} else {BOX_2D;} us_framebox(im1, box, PIX_MAX); uc_framebox(im2, box, 0); /* set shift array */ set_seq_shift(GetImNx(im1), GetImNy(im1), GetImNz(im1), graph, shft); /* Here we go */ nelem = GetImNPix(im1); pim2=(UCHAR *)GetImPtr(im2); for (i=0; i 1) {BOX_3D;} else {BOX_2D;} i32_framebox(im1, box, PIX_MAX); uc_framebox(im2, box, 0); /* set shift array */ set_seq_shift(GetImNx(im1), GetImNy(im1), GetImNz(im1), graph, shft); /* Here we go */ nelem = GetImNPix(im1); pim2=(UCHAR *)GetImPtr(im2); for (i=0; i. ***********************************************************************/ /* macro definitions for unsigned char data types */ #define FLOATING 0 #define SIGNED 1 #define OVFL_TEST 1 #define PIX_TYPE SHORT #define PIX_MIN SHORT_MIN #define PIX_MAX SHORT_MAX #define BitPerPixel 16 jeolib-miallib-1.1.6/core/c/s_undef.h000066400000000000000000000020101467232417700173460ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned char data types */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef BitPerPixel jeolib-miallib-1.1.6/core/c/segmentation.c000066400000000000000000000256011467232417700204260ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file segmentation.c * @author Dominik Brunner and Pierre Soille * @date * * @details see also \cite brunner-soille2007 */ /*************************************************************************** segmentation.c - description ------------------- Segmentation algorithm for multispectral high resolution satellite images begin : Tue May 11 2004 ***************************************************************************/ #include #include #include "mslabel.h" #include "miallib.h" //#include "OpenClose.h" #include "fifo.h" #include "pqueue.h" #include "determineSize.h" #include "mcisrg.h" #include "string.h" #include "base.h" #include "time.h" /** \addtogroup group_seg * @{ */ /* writeGnuPlotXXX: write data files (.dat) for generating diagrams with gnuplot */ void writeGnuPlot(FILE * fhd, int contrast, long int regionNumber) { char buffer[50]; sprintf(buffer, "%i %li\n",contrast, regionNumber); fputs(buffer, fhd); } void writeGnuPlotFloat(FILE * fhd, int contrast, float value) { char buffer[50]; sprintf(buffer, "%i %f\n",contrast, value); fputs(buffer, fhd); } ERROR_TYPE writeGnuPlotFiles(IMAGE **imap, int nc, IMAGE *labelIm, int graph, int varianz, char * filename, long int regionSize) { long int regionNumber; double value1, value2=0.0, value3=0.0, newValue=0.0, oldValue=0.0; FILE * fhd, * maxFhd; FIFO4 * values; char newFileName[300]; char buffer[100]; int i=1; /* start calculating contrast values */ strcpy(newFileName, filename); sprintf(buffer, "_RS%li",regionSize); strcat(newFileName, buffer); strcat(newFileName, ".dat"); printf("Writing file (255 steps): %s\n", newFileName); values = create_fifo4((long int)255); fhd=fopen(newFileName, "w"); if(!fhd){ printf("File could not be generated!\n"); } else{ for(i=1; i<255;i++){ if(labelImage(imap, nc, labelIm, graph, varianz)==NULL){ free_image(labelIm); return ERROR; } regionNumber = thresholdRegion_Contrast(imap, nc, labelIm, i); fifo4_add(values, regionNumber); writeGnuPlot(fhd, i, regionNumber); printf("%d\t", i); } printf("\n"); fclose(fhd); } strcpy(newFileName, filename); sprintf(buffer, "_RS%li_slope",regionSize); strcat(newFileName, buffer); strcat(newFileName, ".dat"); printf("Write file: %s\n", newFileName); fhd=fopen(newFileName, "w"); if(!fhd){ printf("File could not be generated!\n"); } else{ if(fifo4_empty(values)==0){ i=1; value2=(long int)fifo4_remove(values); value3=(long int) fifo4_remove(values); } while(fifo4_empty(values)==0){ value1=value2; value2=value3; value3=(double) fifo4_remove(values); newValue = (value1-value3)/(float)2; writeGnuPlotFloat(fhd, ++i,newValue); if(newValue>=oldValue){ oldValue=newValue; strcpy(newFileName, filename); sprintf(buffer, "_RS%li_maxValue",regionSize); strcat(newFileName, buffer); strcat(newFileName, ".dat"); printf("Write file: %s\n", newFileName); maxFhd=fopen(newFileName, "w"); sprintf(buffer, "%i %f\n",i, oldValue); fputs(buffer, maxFhd); fclose(maxFhd); } } fclose(fhd); } free_fifo4(values); return NO_ERROR; } /* * getBestContrast: determines the best contrast threshold value for the image * * Parameters: * * imap array of pointer to the channels of an input images * * nc size of imap => number of channels * * labelIm pointer to an image in which the resulting label image is stored * * graph either 4 or 8 * * Return values: * * contrast value if everything is ok * * ERROR if there was an error * */ USHORT getBestContrast(IMAGE **imap, int nc, IMAGE *labelIm, int graph, int varianz) { long int regionNumber, value1, value2=0.0, value3=0.0; int i; double newValue=0, oldValue=0; printf("determine best contrast value!\n"); for(i=1; i=oldValue){ oldValue=newValue; } else return i-2; } } return ERROR; } /* * segementImage: segment multispectral high resolution satellite image * * Parameters: * * imap array of pointer to the channels of an input images * * nc size of imap => number of channels * * graph either 4 or 8 * * varianz varianz which is used to decide whether the pixel still belongs to * the region or not. A varianz of 0 means, that the pixel must have exactly the * same value in all channels than the region, in order to belong to it. * * regionSize size which each regions has at least to be before the algorithm stops * * contrast contrast threshold value which is used for merging the regions with similar contrast. * value < 0 => don't make merging of regions * value = 0 => determine best contrast value automatically * value > 0 => use this value as thresholdvalue * * version version of mcisrg algorithm. Versions are * 0 (compare to whole region) * 1 (compare to original seeds) * 2 (compare to pixel neighbours) * * fndat filename to store data files. Authorised values are * NULL (do not store) * valid pointer to a char * containing a file name. * * Return values: * * region number if everything is ok * * ERROR if there was an error * */ IMAGE *segmentImage(IMAGE **imap, int nc, int graph, int varianz, long int regionSize, int contrast, int version, char *fndat) { long int i, regionNumber=0, oldRegionNumber=0; IMAGE *labelIm=NULL; char fname[256]; for (i = 1; i < nc; i++){ if ( (GetImNx(imap[0]) != GetImNx(imap[i])) || \ (GetImNy(imap[0]) != GetImNy(imap[i])) || \ (GetImDataType(imap[0]) != GetImDataType(imap[i])) ){ sprintf(buf, "Bands of different datatype or dimension!"); errputstr(buf); return NULL; } } labelIm = (IMAGE *)create_image(t_LBL_TYPE, GetImNx(imap[0]), \ GetImNy(imap[0]), GetImNz(imap[0])); if (labelIm==NULL){ sprintf(buf, "segmentImage(): not enough memory\n"); errputstr(buf); return NULL; } for(i=2; i<=regionSize;i++){ printf("%li: before determineRegionSize\n", i); if(labelImage(imap, nc, labelIm, graph, varianz)==NULL){ sprintf(buf, "%li: an error occurred\n", i); errputstr(buf); sprintf(fname,"/tmp/ERROR.tif"); write_tiff(labelIm, fname); sprintf(fname,"/tmp/ERROR[0].tif"); write_tiff(imap[0], fname); free_image(labelIm); return NULL; } sprintf(fname,"/tmp/mcisrgINIT0.tif"); /* write_tiff(imap[0], fname); */ sprintf(fname,"/tmp/labelBEFORE%ld.tif", i); /* write_tiff(labelIm, fname); */ if ((regionNumber = thresholdRegion_Size(labelIm, i)) == 0){ free_image(labelIm); return NULL; } if(oldRegionNumber!=regionNumber){ oldRegionNumber=regionNumber; printf("%li: after determineRegionSize - Number of Regions: %li\n", i, regionNumber); if(mcisrg(imap, nc, labelIm, graph, regionNumber, version) == ERROR){ sprintf(fname,"/tmp/labelAFTER%ld.tif", i); free_image(labelIm); return NULL; } sprintf(fname,"/tmp/labelAFTER%ld.tif", i); /* write_tiff(labelIm, fname); */ printf("%li: after mcisrg\n", i); } } sprintf(fname,"/tmp/mcisrgINIT1.tif"); /* write_tiff(imap[0], fname); */ if (fndat!=NULL) writeGnuPlotFiles(imap, nc, labelIm, graph, varianz, fndat, regionSize); if(contrast==0){ contrast = getBestContrast(imap, nc, labelIm, graph, varianz); printf("best contrast value= %d\n", contrast); } sprintf(fname,"/tmp/mcisrgINIT2.tif"); /* write_tiff(imap[0], fname); */ if(contrast>0){ /* then make merge of regions with similar contrast value */ if(labelImage(imap, nc, labelIm, graph, varianz)==NULL){ free_image(labelIm); return NULL; } if ((regionNumber = thresholdRegion_Contrast(imap, nc, labelIm, contrast))==0){ free_image(labelIm); return NULL; } sprintf(fname,"/tmp/mcisrgINIT3.tif"); /* write_tiff(imap[0], fname); */ if(mcisrg(imap, nc, labelIm, graph, regionNumber, version) == ERROR){ free_image(labelIm); return NULL; } } return labelIm; } ERROR_TYPE writeGnuPlot3D(IMAGE **imap, int nc, int graph, int regionSize, int varianz, char * fileName) { long int regionNumber; int i,j; IMAGE * labelIm; char outputFName[1000], buffer[100]; FILE * fhd; strncpy( outputFName, fileName, sizeof(outputFName)-4 ); for( i = strlen(outputFName)-1; i > 0; i-- ){ if( outputFName[i] == '.' ){ strcpy( outputFName + i, ".dat" ); break; } } if( i <= 0 ) strcat( outputFName, ".dat" ); printf("write GnuPlot dat file: %s\n", outputFName); fhd=fopen(outputFName, "w"); if(!fhd){ sprintf(buf, "error in writeGnuPlot3D(): File could not be generated!\n"); errputstr(buf); } else{ labelIm = (IMAGE *) create_image(t_LBL_TYPE, GetImNx(imap[0]), GetImNy(imap[0]), 1); for(i=1; i<=regionSize;i++){ for(j=0; j. ***********************************************************************/ /*************************************************************************** segmentation.h - description ------------------- begin : Tue May 11 2004 ***************************************************************************/ #ifndef init_segmentation #define init_segmentation ERROR_TYPE segmentImage(IMAGE **imap, int nc, int connectivity, int varianz, long int regionSize, int contrast, int version, char *fn); #endif jeolib-miallib-1.1.6/core/c/setreg.c000066400000000000000000001203541467232417700172230ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* this file is not cleaned ... old stuff ... */ #include #include #include #include "miallib.h" #include "fifo.h" /** \addtogroup group_label * @{ */ extern int cluster(); extern ERROR_TYPE agglo_cluster(); extern ERROR_TYPE nearest_cluster(); extern ERROR_TYPE knearest_cluster(); #define set_mean_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ psum[*p2] += *p1; \ p1++; \ p2++; \ }\ for (i = 0; i < maxlbl; ++i){\ if (pnbr[i]) \ psum[i] /= pnbr[i]; \ } \ psum[0] = 0; \ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 = (TYPE2) psum[*p2]; \ p2++;\ } \ } #define set_max_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ if (psum[*p2]<*p1) \ psum[*p2]=*p1; \ p1++; \ p2++; \ }\ psum[0] = 0; \ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 = (TYPE2) psum[*p2]; \ p2++;\ } \ } #define set_min_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ if (psum[*p2]>*p1) \ psum[*p2]=*p1; \ p1++; \ p2++; \ }\ psum[0] = 0; \ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 = (TYPE2) psum[*p2]; \ p2++;\ } \ } #define set_range_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ if (pmin[*p2]>*p1) \ pmin[*p2]=*p1; \ if (pmax[*p2]<*p1) \ pmax[*p2]=*p1; \ p1++; \ p2++; \ }\ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 =(TYPE2) (pmax[*p2]-pmin[*p2]); \ p2++;\ } \ } #define set_sum_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ psum[*p2]+=*p1; \ p1++; \ p2++; \ }\ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 = (TYPE2) psum[*p2]; \ p2++;\ } \ } #define set_sigma_type(TYPE1, TYPE2, i1, i2) \ {\ TYPE1 *p1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *p2 = (TYPE2 *) GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ psum[*p2] += *p1; \ p1++; \ p2++; \ }\ for (i = 0; i < maxlbl; ++i){\ if (pnbr[i]) \ psum[i] /= pnbr[i]; \ } \ p1 = (TYPE1 *) GetImPtr(i1); \ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ psigma[*p2] += fabs((double)*p1-psum[*p2]); \ p1++; \ p2++; \ }\ for (i = 0; i < maxlbl; ++i){\ if (pnbr[i]) \ psigma[i] /= pnbr[i]; \ } \ p2 = (TYPE2 *)GetImPtr(i2); \ LOOPDN(i, GetImNPix(i1)){ \ *p2 = (TYPE2) psigma[*p2]; \ p2++;\ } \ } extern IMBLOB *create_blob(); ERROR_TYPE tessel_sum(IMAGE *ilbl, IMAGE *ival) { IMAGE *imhst; int i, maxlbl; HST1D_TYPE *psum; imhst = histo1d(ilbl); if (imhst==NULL) return(ERROR); maxlbl = GetImNx(imhst); psum = (HST1D_TYPE *)calloc(maxlbl, sizeof(HST1D_TYPE)); if (psum==NULL){ (void)sprintf(buf,"tessel_sum(): insufficient memory\n"); errputstr(buf); free_image(imhst); return(ERROR); } switch (GetImDataType(ilbl)) { case t_USHORT: switch (GetImDataType(ival)) { case t_UCHAR: set_sum_type(UCHAR, USHORT, ival, ilbl); break; case t_USHORT: set_sum_type(USHORT, USHORT, ival, ilbl); break; case t_INT32: set_sum_type(INT32, USHORT , ival, ilbl); break; case t_FLOAT: set_sum_type(MIALFLOAT, USHORT, ival, ilbl); break; case t_DOUBLE: set_sum_type(DOUBLE, USHORT, ival, ilbl); break; default: free_image(imhst); free((char *)psum); return(ERROR); } break; case t_INT32: switch (GetImDataType(ival)) { case t_UCHAR: set_sum_type(UCHAR, INT32, ival, ilbl); break; case t_USHORT: set_sum_type(USHORT, INT32, ival, ilbl); break; case t_INT32: set_sum_type(INT32, INT32, ival, ilbl); break; case t_FLOAT: set_sum_type(MIALFLOAT, INT32, ival, ilbl); break; case t_DOUBLE: set_sum_type(DOUBLE, INT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); return(ERROR); } break; case t_UINT32: switch (GetImDataType(ival)) { case t_UCHAR: set_sum_type(UCHAR, UINT32, ival, ilbl); break; case t_USHORT: set_sum_type(USHORT, UINT32, ival, ilbl); break; case t_INT32: set_sum_type(INT32, UINT32, ival, ilbl); break; case t_FLOAT: set_sum_type(MIALFLOAT, UINT32, ival, ilbl); break; case t_DOUBLE: set_sum_type(DOUBLE, UINT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); return(ERROR); } break; default: free_image(imhst); free((char *)psum); return(ERROR); } free_image(imhst); free((char *)psum); return(NO_ERROR); } ERROR_TYPE tessel_range(IMAGE *ilbl, IMAGE *ival) { IMAGE *imhst; mia_size_t i, maxlbl; DOUBLE *pmin, *pmax; imhst = histo1d(ilbl); if (imhst==NULL) return(ERROR); maxlbl = GetImNx(imhst); pmin = (DOUBLE *)calloc(maxlbl+1, sizeof(DOUBLE)); if (pmin==NULL){ (void)sprintf(buf,"tessel_range(): insufficient memory\n"); errputstr(buf); free_image(imhst); return(ERROR); } pmax = (DOUBLE *)calloc(maxlbl+1, sizeof(DOUBLE)); if (pmax==NULL){ (void)sprintf(buf,"tessel_range(): insufficient memory\n"); errputstr(buf); free((char *)pmin); free_image(imhst); return(ERROR); } for(i=0;i<=maxlbl;i++){ pmin[i]=DOUBLE_MAX; pmax[i]=DOUBLE_MIN; } switch (GetImDataType(ilbl)) { case t_USHORT: switch (GetImDataType(ival)) { case t_UCHAR: set_range_type(UCHAR, USHORT, ival, ilbl); break; case t_USHORT: set_range_type(USHORT, USHORT, ival, ilbl); break; case t_INT32: set_range_type(INT32, USHORT , ival, ilbl); break; case t_FLOAT: set_range_type(MIALFLOAT, USHORT, ival, ilbl); break; case t_DOUBLE: set_range_type(DOUBLE, USHORT, ival, ilbl); break; default: free_image(imhst); free((char *)pmin); free((char *)pmax); (void)sprintf(buf,"tessel_range(): invalid ival data type\n"); errputstr(buf); return(ERROR); } break; case t_INT32: switch (GetImDataType(ival)) { case t_UCHAR: set_range_type(UCHAR, INT32, ival, ilbl); break; case t_USHORT: set_range_type(USHORT, INT32, ival, ilbl); break; case t_INT32: set_range_type(INT32, INT32, ival, ilbl); break; case t_FLOAT: set_range_type(MIALFLOAT, INT32, ival, ilbl); break; case t_DOUBLE: set_range_type(DOUBLE, INT32, ival, ilbl); break; default: free_image(imhst); free((char *)pmin); free((char *)pmax); (void)sprintf(buf,"tessel_range(): invalid ival data type\n"); errputstr(buf); return(ERROR); } break; default: free_image(imhst); free((char *)pmin); free((char *)pmax); (void)sprintf(buf,"tessel_range(): invalid ilbll data type\n"); errputstr(buf); return(ERROR); } free_image(imhst); free((char *)pmin); free((char *)pmax); return(NO_ERROR); } ERROR_TYPE tessel_mean(IMAGE *ilbl, IMAGE *ival) { IMAGE *imhst; int i, maxlbl; HST1D_TYPE *pnbr, *psum; imhst = histo1d(ilbl); if (imhst==NULL) return(ERROR); maxlbl = GetImNx(imhst); pnbr = (HST1D_TYPE *)GetImPtr(imhst); psum = (HST1D_TYPE *)calloc(maxlbl, sizeof(HST1D_TYPE)); if (psum==NULL){ (void)sprintf(buf,"tessel_mean(): insufficient memory\n"); errputstr(buf); free_image(imhst); return(ERROR); } switch (GetImDataType(ival)){ case t_UCHAR: switch (GetImDataType(ilbl)){ case t_UCHAR: set_mean_type(UCHAR, UCHAR, ival, ilbl); break; case t_USHORT: set_mean_type(UCHAR, USHORT, ival, ilbl); break; case t_INT32: set_mean_type(UCHAR, INT32, ival, ilbl); break; case t_UINT32: set_mean_type(UCHAR, UINT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); (void)sprintf(buf,"tessel_mean(): data type of ilbl not allowed\n"); errputstr(buf); return(ERROR); } break; case t_USHORT: switch (GetImDataType(ilbl)){ case t_UCHAR: set_mean_type(USHORT, UCHAR, ival, ilbl); break; case t_USHORT: set_mean_type(USHORT, USHORT, ival, ilbl); break; case t_INT32: set_mean_type(USHORT, INT32, ival, ilbl); break; case t_UINT32: set_mean_type(USHORT, UINT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); (void)sprintf(buf,"tessel_mean(): data type of ilbl not allowed\n"); errputstr(buf); return(ERROR); } break; case t_INT32: switch (GetImDataType(ilbl)){ case t_UCHAR: set_mean_type(INT32, UCHAR, ival, ilbl); break; case t_USHORT: set_mean_type(INT32, USHORT, ival, ilbl); break; case t_INT32: set_mean_type(INT32, INT32, ival, ilbl); break; case t_UINT32: set_mean_type(INT32, UINT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); (void)sprintf(buf,"tessel_mean(): data type of ilbl not allowed\n"); errputstr(buf); return(ERROR); } break; case t_UINT32: switch (GetImDataType(ilbl)){ case t_UCHAR: set_mean_type(UINT32, UCHAR, ival, ilbl); break; case t_USHORT: set_mean_type(UINT32, USHORT, ival, ilbl); break; case t_INT32: set_mean_type(UINT32, INT32, ival, ilbl); break; case t_UINT32: set_mean_type(UINT32, UINT32, ival, ilbl); break; default: free_image(imhst); free((char *)psum); (void)sprintf(buf,"tessel_mean(): data type of ilbl not allowed\n"); errputstr(buf); return(ERROR); } break; default: free_image(imhst); free((char *)psum); (void)sprintf(buf,"tessel_mean(): data type of ival not allowed\n"); errputstr(buf); return(ERROR); } free_image(imhst); free((char *)psum); return(NO_ERROR); } ERROR_TYPE tessel_min(IMAGE *ilbl, IMAGE *ival) { IMAGE *imhst; int i, maxlbl; HST1D_TYPE *psum; imhst = histo1d(ilbl); if (imhst==NULL) return(ERROR); maxlbl = GetImNx(imhst); psum = (HST1D_TYPE *)calloc(maxlbl, sizeof(HST1D_TYPE)); for (i=0; iarea +=1; blob->m00 += val; blob->m10 += (x*val); blob->m01 += (y*val); } } for(i=1; ixcg; ycg=blob->ycg; blob->mu11 += (x-xcg)*(y-ycg)*val; blob->mu20 += (x-xcg)*(x-xcg)*val; blob->mu02 += (y-ycg)*(y-ycg)*val; } } for(i=1; i 0) phi+=(PI/2); else if (mu11 < 0) phi-=(PI/2); else phi=PI/2; } if (phi<0.0) phi+=PI; } else if (mu11 > 0) phi=(PI/4); else if (mu11 < 0) phi=(3*PI/4); else phi=0; part[i].dir = (UCHAR)(255.0*phi/PI); /* 255 for label 0 */ } else if (type==10){ /* calculate the correlation coefficient */ mu20/=area; mu02/=area; mu11/=area; if (mu20>2.0 && mu02>2.0){ r=mu11/sqrt(mu20*mu02); slope=r*sqrt(mu02)/sqrt(mu20); cst=ycg-r*xcg*sqrt(mu02*mu20)*area; (void)sprintf(buf,"LR: lbl=%d\t slope=%f\t offset=%f\t r=%f\n", (int)i, (float)slope, (float)cst, (float)r); stdputstr(buf); } else if (mu20<=2.0){ (void)sprintf(buf,"linear regression for particle %ld outputs a vertical line\n", i); stdputstr(buf); r=1; } else if (mu02<=2.0){ (void)sprintf(buf,"linear regression for particle %ld outputs a horizontal line\n", i); stdputstr(buf); r=1; } part[i].r=r; } else if (type==11 || type==13 || type==14 || type==15){ /* compute the ratio of length of the semi minor and major axis */ c=sqrt((mu20-mu02)*(mu20-mu02)+4*mu11*mu11); ratio=sqrt((mu20+mu02+c)/(mu20+mu02-c)); //(void)sprintf(buf,"ellipsis ratio of particle %d = %f\n", i, (float)ratio); stdputstr(buf); part[i].ratio=ratio; part[i].minor=(int)(2*sqrt(2*(mu20+mu02-c)/m00)); //(void)sprintf(buf,"minor axis particle %d = %d\n", i, part[i].minor); stdputstr(buf); part[i].major=(int)(2*sqrt(2*(mu20+mu02+c)/m00)); //(void)sprintf(buf,"major axis particle %d = %d\n", i, part[i].major); stdputstr(buf); part[i].irradiance=255 * 4*m00/(PI*part[i].minor*part[i].major); //(void)sprintf(buf,"irradiance particle %d = %d\n", i, part[i].irradiance); stdputstr(buf); } } part[0].dir = 255; part[0].ratio = 0; part[0].r = 0; part[0].minor=0; part[0].major=0; /* set each blob to its its computed value */ if (type==11){ /* gravity centre */ for (i=1; i1) pilbl[i]=lblt[pilbl[i]-2]+1; for (i=0; imaxfreq){ lblmaj=j; maxfreq=*(ptr[i]+j); } } *(ptr[i])=lblmaj; } **ptr=0; /* that's the background */ plbl=(USHORT *)GetImPtr(ilbl); LOOPDN(i, GetImNPix(ilbl)){ if (*plbl) *plbl=*(ptr[*plbl]); plbl++; } for (i=0; imaxfreq){ lblmaj=j; maxfreq=*(ptr[i]+j); } } *(ptr[i])=lblmaj; } **ptr=0; /* that's the background */ plbl=(USHORT *)GetImPtr(ilbl); LOOPDN(i, GetImNPix(ilbl)){ if (*plbl) *plbl=*(ptr[*plbl]); plbl++; } for (i=0; imaxfreq){ lblmaj=j; maxfreq=*(ptr[i]+j); } } *(ptr[i])=lblmaj; } **ptr=0; /* that's the background */ plbl=(INT32 *)GetImPtr(ilbl); LOOPDN(i, GetImNPix(ilbl)){ if (*plbl) *plbl=*(ptr[*plbl]); plbl++; } for (i=0; i moyenne de la zone * - 2 ---> ecart-type * - 3 ---> maximum * - 4 ---> minimum * - 5 ---> max - min * - 6 ---> (max + min) / 2 * - 7 ---> label du premier pixel non nul de la zone * - 8 ---> sum of the grey levels of the zone * - 9 ---> valeur correspondant a l'orientation codee enter 0 et 255 * -10 ---> correlation coefficient of each blob * -11 ---> compute gravity centre * -12 ---> use majority rule for neighbours to the region * -13 ---> set blob to length of minor axis * -14 ---> set blob to length of major axis * -15 ---> irradiance of equivalent ellipse fit *255 * * Sortie: imlbl = image ou chacune des zones precedentes a une * nouvelle valeur, determinee a l'aide de indic * et de imval. Seuls les pixels * initialement a 0 dans imlbl ne sont pas touches. */ /* error checking */ if ( (indic == 1) || (indic == 3) || (indic == 4) || (indic == 8) || (indic == 12) || (indic == 20) ){ if (GetImNPix(ilbl) != GetImNPix(ival) ){ (void)sprintf(buf, "ERROR in set_regions(): \ images of different size \n"); errputstr(buf); return(ERROR); } } else if ( (GetImNPix(ilbl) != GetImNPix(ival)) ||\ (GetImDataType(ilbl) != t_LBL_TYPE) ){ (void)sprintf(buf, "ERROR in set_regions(): \ images of different size or \ label image not of type t_LBL_TYPE\n"); errputstr(buf); return(ERROR); } switch (indic){ case 1: return(tessel_mean(ilbl, ival)); break; case 2: return(tessel_sigma(ilbl, ival)); break; case 3: return(tessel_max(ilbl, ival)); break; case 4: return(tessel_min(ilbl, ival)); break; case 8: return(tessel_sum(ilbl, ival)); break; case 9: /* orientation of matching ellipsis */ case 10: /* correlation coefficient */ case 11: /* gravity centre */ case 13: /* minor axis of matching ellipsis */ case 14: /* major axis of matching ellipsis */ case 15: /* irradiance */ case 16: /* agglomerative clustering */ case 17: /* nearest neighbours */ case 18: /* k nearest neighbours */ case 19: /* CURE hierarchical clustering */ return(uc_tessel_dir(ilbl,ival,indic)); break; case 12: return(tessel_majorityngb(ilbl,ival)); break; case 20: return(tessel_range(ilbl,ival)); break; default: (void)sprintf(buf, "ERROR in set_regions(): \ invalid indicator number\n"); errputstr(buf); } return ERROR; } #include "uc_def.h" /* ival image */ ERROR_TYPE uc_setregionsgraph(IMAGE *ilbl, IMAGE *ival, int indic, int graph) { int i, j, k; G_TYPE *pg; UINT32 *plbl, maxlbl; PIX_TYPE *ptrmin, *ptrmax; PIX_TYPE *ptrmind, *ptrmaxd; int nx=GetImNx(ilbl); int ny=GetImNy(ilbl); PIX_TYPE *pval; long int shft[27]; /* take graph into account */ if (set_seq_shift(GetImNx(ilbl), GetImNy(ilbl), GetImNz(ilbl), graph, shft) == ERROR) return ERROR; /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(ERROR); maxlbl = pg[1].u32_val; free((char *)pg); /* allocate memory for histograms of neighbouring pixels of each labelled region */ ptrmin = (PIX_TYPE *)calloc(maxlbl+1,sizeof(PIX_TYPE)); ptrmax = (PIX_TYPE *)calloc(maxlbl+1,sizeof(PIX_TYPE)); for (i=0; i *pval) ptrmin[*(plbl+shft[k])]=*pval; else if ( ptrmax[*(plbl+shft[k])] < *pval) ptrmax[*(plbl+shft[k])]=*pval; if ( ptrmind[*(plbl+shft[k])] > abs( (int) *pval-*(pval+shft[k])) ) ptrmind[*(plbl+shft[k])]=abs( (int) *pval-*(pval+shft[k])); else if ( ptrmaxd[*(plbl+shft[k])] < abs( (int) *pval-*(pval+shft[k]))) ptrmaxd[*(plbl+shft[k])]=abs( (int) *pval-*(pval+shft[k])); } } pval++; plbl++; } pval+=2; plbl+=2; } plbl=(UINT32 *)GetImPtr(ilbl); LOOPDN(i, GetImNPix(ilbl)){ if (indic==0) *plbl=ptrmin[*plbl]; else if (indic==1) *plbl=ptrmax[*plbl]; else if (indic==2) *plbl=ptrmax[*plbl]-ptrmin[*plbl]; else if (indic==3) *plbl=ptrmind[*plbl]; else if (indic==4) *plbl=ptrmaxd[*plbl]; else if (indic==5) *plbl=ptrmaxd[*plbl]-ptrmind[*plbl]; plbl++; } free((char *)ptrmin); free((char *)ptrmax); return(NO_ERROR); } #include "uc_undef.h" ERROR_TYPE setregionsgraph(IMAGE *ilbl, IMAGE *ival, int indic, int graph) { if ( (GetImNPix(ilbl) != GetImNPix(ival)) || \ (GetImDataType(ilbl) != t_LBL_TYPE) ){ (void)sprintf(buf, "ERROR in setregionsgraph(): \ images of different size or \ label image not of type t_LBL_TYPE\n"); errputstr(buf); return(ERROR); } return uc_setregionsgraph(ilbl, ival, indic, graph); } #ifndef NO_generic_IMAGE #include "g_def.h" ERROR_TYPE generic_tessel_surface(IMAGE *im) { PIX_TYPE *p; int i, count=0; HST1D_TYPE *pnbr; IMAGE *imhst; imhst=histo1d(im); if (imhst==NULL) return ERROR; pnbr = (HST1D_TYPE *) GetImPtr(imhst); p = (PIX_TYPE *)GetImPtr(im); pnbr[0]=0; /* force background to zero */ LOOPDN(i, GetImNPix(im)){ if (pnbr[*p]>PIX_MAX){ count+=1; pnbr[*p]=PIX_MAX; } *p = pnbr[*p]; p++; } if (count){ (void)sprintf(buf,"%d regions have an area greater than PIX_MAX, output value saturated at PIX_MAX\n", count); errputstr(buf); } free_image(imhst); return NO_ERROR; } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "i32_def.h" ERROR_TYPE i32_tessel_surface(IMAGE *im) { PIX_TYPE *p; int i, count=0; HST1D_TYPE *pnbr; IMAGE *imhst; imhst=histo1d(im); if (imhst==NULL) return ERROR; pnbr = (HST1D_TYPE *) GetImPtr(imhst); p = (PIX_TYPE *)GetImPtr(im); pnbr[0]=0; /* force background to zero */ LOOPDN(i, GetImNPix(im)){ if (pnbr[*p]>PIX_MAX){ count+=1; pnbr[*p]=PIX_MAX; } *p = pnbr[*p]; p++; } if (count){ (void)sprintf(buf,"%d regions have an area greater than PIX_MAX, output value saturated at PIX_MAX\n", count); errputstr(buf); } free_image(imhst); return NO_ERROR; } #include "i32_undef.h" #include "u32_def.h" ERROR_TYPE u32_tessel_surface(IMAGE *im) { PIX_TYPE *p; int i, count=0; HST1D_TYPE *pnbr; IMAGE *imhst; imhst=histo1d(im); if (imhst==NULL) return ERROR; pnbr = (HST1D_TYPE *) GetImPtr(imhst); p = (PIX_TYPE *)GetImPtr(im); pnbr[0]=0; /* force background to zero */ LOOPDN(i, GetImNPix(im)){ if (pnbr[*p]>PIX_MAX){ count+=1; pnbr[*p]=PIX_MAX; } *p = pnbr[*p]; p++; } if (count){ (void)sprintf(buf,"%d regions have an area greater than PIX_MAX, output value saturated at PIX_MAX\n", count); errputstr(buf); } free_image(imhst); return NO_ERROR; } #include "u32_undef.h" #include "us_def.h" ERROR_TYPE us_tessel_surface(IMAGE *im) { PIX_TYPE *p; int i, count=0; HST1D_TYPE *pnbr; IMAGE *imhst; imhst=histo1d(im); if (imhst==NULL) return ERROR; pnbr = (HST1D_TYPE *) GetImPtr(imhst); p = (PIX_TYPE *)GetImPtr(im); pnbr[0]=0; /* force background to zero */ LOOPDN(i, GetImNPix(im)){ if (pnbr[*p]>PIX_MAX){ count+=1; pnbr[*p]=PIX_MAX; } *p = pnbr[*p]; p++; } if (count){ (void)sprintf(buf,"%d regions have an area greater than PIX_MAX, output value saturated at PIX_MAX\n", count); errputstr(buf); } free_image(imhst); return NO_ERROR; } #include "us_undef.h" /* ** Set each region of partioned image im to ** the its corresponding surface. */ ERROR_TYPE tessel_surface(IMAGE *im) { switch (GetImDataType(im)) { case t_UCHAR: return generic_tessel_surface(im); break; case t_USHORT: return us_tessel_surface(im); break; case t_INT32: return i32_tessel_surface(im); break; case t_UINT32: return u32_tessel_surface(im); break; default: return(ERROR); } } #define set_lbl2lbl_type(TYPE1, TYPE2, i1, i2, i3) \ { \ TYPE1 *plbl1 = (TYPE1 *) GetImPtr(i1); \ TYPE2 *plbl2 = (TYPE2 *) GetImPtr(i2); \ TYPE1 *pval2 = (TYPE1 *) GetImPtr(i3); \ LOOPDN(i, GetImNPix(i1)){ \ if (parea[*plbl1]<*pval2){ \ parea[*plbl1]=*pval2; \ plbl[*plbl1]=*plbl2; \ } \ plbl1++; \ plbl2++; \ pval2++; \ }\ plbl1 = (TYPE1 *)GetImPtr(i1); \ LOOPDN(i, GetImNPix(i1)){ \ *plbl1 = plbl[*plbl1]; \ plbl1++;\ } \ } #include "u32_def.h" ERROR_TYPE u32_relabel(IMAGE *ilbl1, IMAGE *ilbl2, IMAGE *iarea2) { G_TYPE *pg; PIX_TYPE maxlbl1; PIX_TYPE *parea, *plbl; unsigned long int i; /* get max lbl in ilbl1 */ pg = min_max(ilbl1); if (pg == NULL) return(ERROR); maxlbl1 = pg[1].u32_val +1; free((char *)pg); parea = (PIX_TYPE *)calloc(maxlbl1, sizeof(PIX_TYPE)); if (parea==NULL){ (void)sprintf(buf,"(): insufficient memory\n"); errputstr(buf); } plbl = (PIX_TYPE *)calloc(maxlbl1, sizeof(PIX_TYPE)); if (plbl==NULL){ free(parea); (void)sprintf(buf,"(): insufficient memory\n"); errputstr(buf); } set_lbl2lbl_type(UINT32, UINT32, ilbl1, ilbl2, iarea2); free(parea); free(plbl); return NO_ERROR; } #include "u32_undef.h" ERROR_TYPE relabel(IMAGE *ilbl1, IMAGE *ilbl2, IMAGE *iarea2) { switch (GetImDataType(ilbl1)){ case t_UINT32: case t_INT32: return u32_relabel(ilbl1, ilbl2, iarea2); break; default: return(ERROR); } } /*@}*/ jeolib-miallib-1.1.6/core/c/setreglut.c000066400000000000000000002041211467232417700177430ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2010-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* started September 2010 */ #include #include #include #include #include "miallib.h" #include "fifo.h" #include "pqueue.h" #ifdef OPENMP #include #endif /** \addtogroup group_label * @{ */ #include "u32_def.h" #define LUT_TYPE MIALFLOAT IMAGE *u32_region_lut_no_omp(IMAGE *ilbl, int graph, int type) { // first: 20100914 G_TYPE *pg; PIX_TYPE maxlbl, *plbl, lbl; IMAGE *lut; FIFO4 *q; LUT_TYPE *plut; long int shft[27]; unsigned long int n, npix, ofs; int i, k, x, y, nx, ny; int xi, yi, xmin, xmax, ymin, ymax, xw, yw; double sx, sy, sx2, sy2; int box[6]; nx=GetImNx(ilbl); ny=GetImNy(ilbl); npix=GetImNPix(ilbl); plbl=(PIX_TYPE *)GetImPtr(ilbl); /* we can proceed with queues or without: here version with a queue which requires a bit for flagging */ /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, PIX_MSB); printf("maxlbl=%d\n", (int)maxlbl); /* treat one region after the other using queues */ switch (type){ case 0: /* bounding box */ lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 1); if (lut==NULL){ (void)sprintf(buf,"region_lut(): not enough memory for lut\n"); return NULL; } plut=(LUT_TYPE *)GetImPtr(lut); *plut=0.0; q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_lut(): not enough memory for the FIFO\n"); free_image(lut); return NULL; } for (y=1; yxi) xmin=xi; if(xmaxxi) xmin=xi; if(xmaxparam1) ){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->offset=ofs+shft[k]; pqd->prio=plbl[ofs+shft[k]]&PIX_NMSB; pqmininsert(pq,pqd); /* add edge dissim to pqueue */ } } while (fifo4_empty(q) == FALSE){ ofs=fifo4_remove(q); for(k=0;kparam1) ){ pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->offset=ofs+shft[k]; pqd->prio=plbl[ofs+shft[k]]&PIX_NMSB; pqmininsert(pq,pqd); /* add edge dissim to pqueue */ } } } free_fifo4(q); //printf("region_lut(): look for majority label!!!!\n"); /* look for majority label */ ncrt=0; nmax=0; if (pqpeek(pq, apqd) != NULL){ priocrt=apqd[0]->prio; lblmax=priocrt; } while (pqminremove(pq, apqd) != NULL){ //ofs=apqd[0]->offset; prio=apqd[0]->prio; free((char*) *apqd); ncrt++; //printf("region_lut(): prio=%u!!!!\n", prio); if (prio!=priocrt){ if(nmax=2) plut[lbl]=(float)lblmax; else plut[lbl]=lbl; free_pq(pq); } } free_image(imlutarea); } break; case 6: /* moment of order p=param1 q=param2 */ { double mpq, dparam1=(double) param1, dparam2=(double)param2; #ifdef OPENMP #pragma omp parallel for shared(plut,plutlbl,plbl,shft) private(i,q,ofs,lbl,k,xi,yi,mpq) schedule(dynamic) #endif for (i=1;i0;i--){ // on continuous labels 20120420 //for (i=1; i<=maxlbl; i++){ // lbl==0 for background or border //#pragma omp task untied shared(plut,plutlbl,plbl,shft) private(q,ofs,lbl,k,n,xi,yi,sum_x,sum_y,sum_x2,sum_y2,sum_xy,mu11,mu20,mu02,a,b,theta) firstprivate(i) ofs=plutlbl[i]; if (ofs==0) continue; if ( !(PIX_MSB & plbl[ofs]) ){ // label not yet processed q = create_fifo4(1024L); if (q==NULL){ (void) printf("region_lut(): not enough memory for the FIFO in an OMP statement!!!!\n"); printf("label=%ld not treated!!!\n", i); continue; } lbl=plbl[ofs]; plbl[ofs]|=PIX_MSB; n=1; xi=ofs%nx; yi=ofs/nx; sum_x=xi; sum_y=yi; sum_x2=(xi*xi); sum_y2=(yi*yi); sum_xy=(xi*yi); for(k=0;k0.0) theta=-PI/4.0; else theta=0.0; theta*=rad2deg; plut[lbl] =(float)a; plut[maxlbl+1+lbl] =(float)b; plut[(2*maxlbl)+2+lbl]=(float)theta; free_fifo4(q); } } } break; default: (void)sprintf(buf,"region_lut(): invalid operation type\n"); return NULL; } /* reset label image */ #ifdef OPENMP #pragma omp parallel for #endif for (i=0; ipim[i]) plut[plbl[i]]=pim[i]; } break; #if SIGNED==0 case 5: /* percentile */ /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxim = pg[1].uc_val; free((char *)pg); hst=(unsigned int *)calloc((size_t)maxim+1, sizeof(unsigned int)); BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, LBL_PIX_MSB); lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 1); if (lut==NULL){ free(hst); return NULL; } plut=(LUT_TYPE *)GetImPtr(lut); q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_im_lut(): not enough memory for the FIFO\n"); free(hst); free_image(lut); return NULL; } for (y=1; y=n) break; } plut[lbl]=i; /* reset histogram */ memset(hst, 0, sizeof(unsigned int)*(maxim+1)); } } } free_fifo4(q); free(hst); /* reset label image */ #ifdef OPENMP #pragma omp parallel for #endif for (i=0; ipim[i]) plut2[plbl[i]]=pim[i]; } #ifdef OPENMP #pragma omp parallel for #endif for (i=0;i<=maxlbl; i++) plut[i]-=plut2[i]; free_image(lut2); } break; default: (void)sprintf(buf,"region_im_lut(): invalid operation type\n"); errputstr(buf); return NULL; } return lut; } #undef LBL_PIX_TYPE #undef LBL_PIX_MSB #undef LUT_TYPE #include "uc_undef.h" #include "us_def.h" #define LUT_TYPE MIALFLOAT #define LBL_PIX_TYPE UINT32 #define LBL_PIX_MSB 0x80000000 IMAGE *us_region_im_lut(IMAGE *ilbl, IMAGE *im, int graph, int type, float aval) { // first: 20110412 G_TYPE *pg; PIX_TYPE *pim, newval, maxim; LBL_PIX_TYPE maxlbl, *plbl, lbl; IMAGE *lut; FIFO4 *q; LUT_TYPE *plut; long int shft[27]; unsigned long int n, npix, ofs; long int i; int xi, yi, k, x, y, nx, ny; int box[6]; unsigned int *hst, count; nx=GetImNx(ilbl); ny=GetImNy(ilbl); npix=GetImNPix(ilbl); plbl=(LBL_PIX_TYPE *)GetImPtr(ilbl); pim=(PIX_TYPE *)GetImPtr(im); /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); /* treat one region after the other using queues */ switch (type){ case 0: /* least square 3D plane fitting http://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf */ /* we can proceed with queues or without: here version with a queue which requires a bit for flagging */ BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, LBL_PIX_MSB); lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 4); if (lut==NULL) return NULL; plut=(LUT_TYPE *)GetImPtr(lut); q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_im_lut(): not enough memory for the FIFO\n"); free_image(lut); return NULL; } double sx2, sy2, sx, sy, sxy, sz, sxz, syz; double det, a, b, c, d, e, f, A, B, C; for (y=1; ypim[i]) plut[plbl[i]]=pim[i]; } break; #if SIGNED==0 case 5: /* percentile */ /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxim = pg[1].us_val; free((char *)pg); hst=(unsigned int *)calloc((size_t)maxim+1, sizeof(unsigned int)); BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, LBL_PIX_MSB); lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 1); if (lut==NULL){ free(hst); return NULL; } plut=(LUT_TYPE *)GetImPtr(lut); q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_im_lut(): not enough memory for the FIFO\n"); free(hst); free_image(lut); return NULL; } for (y=1; y=n) break; } plut[lbl]=i; /* reset histogram */ memset(hst, 0, sizeof(unsigned int)*(maxim+1)); } } } free_fifo4(q); free(hst); /* reset label image */ #ifdef OPENMP #pragma omp parallel for #endif for (i=0; ipim[i]) plut2[plbl[i]]=pim[i]; } #ifdef OPENMP #pragma omp parallel for #endif for (i=0;i<=maxlbl; i++) plut[i]-=plut2[i]; free_image(lut2); } break; default: (void)sprintf(buf,"region_im_lut(): invalid operation type\n"); errputstr(buf); return NULL; } return lut; } #undef LBL_PIX_TYPE #undef LBL_PIX_MSB #undef LUT_TYPE #include "us_undef.h" #include "f_def.h" #define LUT_TYPE MIALFLOAT #define LBL_PIX_TYPE UINT32 #define LBL_PIX_MSB 0x80000000 IMAGE *f_region_im_lut(IMAGE *ilbl, IMAGE *im, int graph, int type, float aval) { // first: 20110412 G_TYPE *pg; PIX_TYPE *pim, newval; LBL_PIX_TYPE maxlbl, *plbl, lbl; IMAGE *lut; FIFO4 *q; LUT_TYPE *plut; long int shft[27]; unsigned long int n, npix, ofs; long int i; int xi, yi, k, x, y, nx, ny; int box[6]; nx=GetImNx(ilbl); ny=GetImNy(ilbl); npix=GetImNPix(ilbl); plbl=(LBL_PIX_TYPE *)GetImPtr(ilbl); pim=(PIX_TYPE *)GetImPtr(im); /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); /* treat one region after the other using queues */ switch (type){ case 0: /* least square 3D plane fitting http://www.geometrictools.com/Documentation/LeastSquaresFitting.pdf */ /* we can proceed with queues or without: here version with a queue which requires a bit for flagging */ BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, LBL_PIX_MSB); lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 4); if (lut==NULL) return NULL; plut=(LUT_TYPE *)GetImPtr(lut); q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_im_lut(): not enough memory for the FIFO\n"); free_image(lut); return NULL; } double sx2, sy2, sx, sy, sxy, sz, sxz, syz; double det, a, b, c, d, e, f, A, B, C; for (y=1; ypim[i]) plut[plbl[i]]=pim[i]; } break; #if SIGNED==0 case 5: /* percentile */ /* get min & max values */ pg = min_max(im); if (pg == NULL) return(NULL); maxim = pg[1].f_val; free((char *)pg); hst=(unsigned int *)calloc((size_t)maxim+1, sizeof(unsigned int)); BOX_2D; set_seq_shift(nx, ny, GetImNz(ilbl), graph, shft); u32_framebox(ilbl, box, LBL_PIX_MSB); lut= (IMAGE *)create_image(t_FLOAT, maxlbl+1, 1, 1); if (lut==NULL){ free(hst); return NULL; } plut=(LUT_TYPE *)GetImPtr(lut); q = create_fifo4((nx*ny)/100+1); if (q==NULL){ (void) printf("region_im_lut(): not enough memory for the FIFO\n"); free(hst); free_image(lut); return NULL; } for (y=1; y=n) break; } plut[lbl]=i; /* reset histogram */ memset(hst, 0, sizeof(unsigned int)*(maxim+1)); } } } free_fifo4(q); free(hst); /* reset label image */ #ifdef OPENMP #pragma omp parallel for #endif for (i=0; ipim[i]) plut2[plbl[i]]=pim[i]; } #ifdef OPENMP #pragma omp parallel for #endif for (i=0;i<=maxlbl; i++) plut[i]-=plut2[i]; free_image(lut2); } break; default: (void)sprintf(buf,"region_im_lut(): invalid operation type\n"); errputstr(buf); return NULL; } return lut; } #undef LBL_PIX_TYPE #undef LBL_PIX_MSB #undef LUT_TYPE #include "f_undef.h" IMAGE *region_im_lut(IMAGE *ilbl, IMAGE *im, int graph, int type, float aval) { /* make sure ilbl t_ype = t_UINT32 */ if (GetImDataType(ilbl) != t_UINT32){ (void)sprintf(buf, "ERROR in region_im_lut(): \ invalid ImDataType for ilbl\n"); errputstr(buf); return(NULL); } switch (GetImDataType(im)){ case t_UCHAR: return uc_region_im_lut(ilbl, im, graph, type, aval); break; case t_USHORT: return us_region_im_lut(ilbl, im, graph, type, aval); break; case t_FLOAT: return f_region_im_lut(ilbl, im, graph, type, aval); break; default: (void)sprintf(buf, "ERROR in region_im_lut(): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } } #include "u32_def.h" #define MY_LUT_TYPE UINT32 #define t_MY_LUT_TYPE t_UINT32 IMAGE *u32_contortion_lut(IMAGE *ilbl, int graph) { /* Processing based on contour representation: returns a LUT indicating for each label its contortion number, that is, the number of times a given direction change its sign. This can be used for shape description and in particular to distinguish random shapes from regular shapes. Idea came on the evening of the 18th of May 2011. Code modified from outercontour function: only points with change of direction are kept. assumes border is set to zero to avoid border overflow. Pierre Soille First 20100930 (for building footprint characterisation) based on Moore's contour tracing algorithm with Jacob's condition, see http://www.thebigblob.com/moore-neighbor-contour-tracing-algorithm-in-c/ by Erik Smistad (see local file moore_tracing.c) extended for label images as well as omp speed-up and graph. Additional image not actually necessary (coding in MSB is enough) but used to return an image with mask of outer edge pixels set to 1 (others to 0). http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html */ G_TYPE *pg; IMAGE *lut; MY_LUT_TYPE *plut; PIX_TYPE *plbl, maxlbl, lbl; IMAGE *imout; UCHAR *pout; int nx=GetImNx(ilbl); long int i, npix, pos; // openMP requires signed loop index // Defines the neighborhood offset position from current position and the neighborhood // position we want to check next if we find a new border at checkLocationNr // 1 2 3 // 0 x 4 // 7 6 5 int neighborhood[8][2] = { {-1,7}, // red {-1-nx,7}, // green {-nx,1}, // blue {-nx+1,1}, // yellow {1,3}, // magenta {1+nx,3}, // cyan {nx,5}, // white {nx-1,5} // grey }; if (graph!=8) graph=4; if (graph==4){ // - 1 - // 0 x 2 // - 3 - neighborhood[0][0] = -1; // red neighborhood[0][1] = 4; neighborhood[1][0] = -nx; // green neighborhood[1][1] = 1; neighborhood[2][0] = 1; // blue neighborhood[2][1] = 2; neighborhood[3][0] = nx; // yellow neighborhood[3][1] = 3; } if (graph!=4){ (void)sprintf(buf, "ERROR in :contortion_lut() \ graph must be equal to 4 at the moment\n"); errputstr(buf); return NULL; } imout=(IMAGE *)create_image(t_UCHAR, GetImNx(ilbl), GetImNy(ilbl), 1); if (imout==NULL) return NULL; /* get min & max values */ pg = min_max(ilbl); if (pg == NULL) return(NULL); maxlbl = pg[1].u32_val; free((char *)pg); lut= (IMAGE *)create_image(t_MY_LUT_TYPE, maxlbl+1, 1, 1); if (lut==NULL){ free_image(imout); return NULL; } plut =(MY_LUT_TYPE *)GetImPtr(lut); plbl =(PIX_TYPE *)GetImPtr(ilbl); pout =(UCHAR *)GetImPtr(imout); npix =GetImNPix(ilbl); plut[0]=1; // dummy value to speed-up next loop /* first collect first point of each CC in an array for subsequent parallel processing */ for (i=0;ivcstmax) vcstmax=vcst; vcst=1; } else vcst++; } else { /* horizontal orientation */ if (hdir==-1){ hdir=dircrt; hcst=1; } else if (hdir!=dircrt){ hdirchange++; hdir=dircrt; if (hcst>hcstmax) hcstmax=hcst; hcst=1; } else hcst++; } pout[pos]=9; pout[checkPosition]=9; prevCheckLocationNr=checkLocationNr; } counter ++; // Stopping criterion (jacob) if(newCheckLocationNr == 1 || counter >= 3) { // Close loop //inside = trueval; // Since we are starting the search at were we first started we must set inside to true break; } } pout[pos]=checkLocationNr; // direction of next border point // set to 9 if point of change of direction if (checkLocationNr!=prevCheckLocationNr){ dircrt= (checkLocationNr-1) % graph; if (dircrt & 0x1){ /* vertical orientation */ if (vdir==0) vdir=dircrt; else if (vdir!=dircrt){ vdirchange++; vdir=dircrt; } } else { /* horizontal orientation */ if (hdir==-1) hdir=dircrt; else if (hdir!=dircrt){ hdirchange++; hdir=dircrt; } } pout[pos]=9; pout[checkPosition]=9; prevCheckLocationNr=checkLocationNr; } checkLocationNr = newCheckLocationNr;// Update which neighborhood position we should check next pos = checkPosition; counter2 = 0; // Reset the counter that keeps track of how many neighbors we have visited } else{ // Rotate clockwise in the neighborhood checkLocationNr = 1 + (checkLocationNr % graph); if(counter2 > graph){ // If counter2 is above 8 we have traced around the neighborhood and // therefore the border is a single black pixel and we can exit counter2 = 0; break; } else{ counter2 ++; } } } //printf("hdirchange=%d vdirchange=%d\n", hdirchange, vdirchange); plut[i]=hdirchange+vdirchange; } } // } /* END of parallel region */ free_image(imout); return lut; } #undef MY_LUT_TYPE #undef t_MY_LUT_TYPE #include "u32_undef.h" IMAGE *contortion_lut(IMAGE *ilbl, int graph) { switch (GetImDataType(ilbl)){ case t_UINT32: return u32_contortion_lut(ilbl, graph); break; default: (void)sprintf(buf, "ERROR in outercontour(IMAGE *ilbl, int graph): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } } #include "f_def.h" IMAGE *f_moments_lut_to_ellipse_lut(IMAGE **impq) { mia_size_t i,n; MIALFLOAT *m00, *m10, *m01, *m11, *m20, *m02; double mu11, mu20, mu02; double denom, a, b, theta, rad2deg=180.0/PI;; IMAGE *lut; MIALFLOAT *plut; m00=(MIALFLOAT *)GetImPtr(impq[0]); m10=(MIALFLOAT *)GetImPtr(impq[1]); m01=(MIALFLOAT *)GetImPtr(impq[2]); m11=(MIALFLOAT *)GetImPtr(impq[3]); m20=(MIALFLOAT *)GetImPtr(impq[4]); m02=(MIALFLOAT *)GetImPtr(impq[5]); n=GetImNPix(impq[0]); lut= (IMAGE *)create_image(t_FLOAT, n, 3, 1); if (lut==NULL) return NULL; plut= (LUT_TYPE *)GetImPtr(lut); for(i=1;i0.0) theta=-PI/4.0; else theta=0.0; theta*=rad2deg; plut[i] =(float)a; plut[n+i] =(float)b; plut[(2*n)+i]=(float)theta; } return(lut); } #include "f_undef.h" IMAGE *moments_lut_to_ellipse_lut(IMAGE **impq) { switch (GetImDataType(impq[0])){ case t_FLOAT: return f_moments_lut_to_ellipse_lut(impq); break; default: (void)sprintf(buf, "ERROR in IMAGE *moments_lut_to_ellipse_lut(IMAGE **impq): \ invalid ImDataType\n"); errputstr(buf); return(NULL); } } /*@}*/ jeolib-miallib-1.1.6/core/c/setshft.c000066400000000000000000000250331467232417700174100ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include "miallib.h" /** @addtogroup group_geom * @{ */ ERROR_TYPE szcompat(IMAGE *im1, IMAGE *im2) { if (GetImNx(im1) != GetImNx(im2)) return(ERROR); else if (GetImNy(im1) != GetImNy(im2)) return(ERROR); else if (GetImNz(im1) != GetImNz(im2)) return(ERROR); else if (GetImDataType(im1) != GetImDataType(im2)) return(ERROR); else if ((GetImPtr(im1) == NULL) || (GetImPtr(im2) == NULL)) return(ERROR); return(NO_ERROR); } ERROR_TYPE szgeocompat(IMAGE *im1, IMAGE *im2) { if (GetImNx(im1) != GetImNx(im2)) return(ERROR); else if (GetImNy(im1) != GetImNy(im2)) return(ERROR); else if (GetImNz(im1) != GetImNz(im2)) return(ERROR); else if ((GetImPtr(im1) == NULL) || (GetImPtr(im2) == NULL)) return(ERROR); return(NO_ERROR); } /* 2007 03 08 */ ERROR_TYPE set_shift(long int nx, long int ny, long int nz, long int graph, long int *shift) { if (graph == 4){ /* && nz == 1: suppressed on 2004-11-18 (side effects?) */ shift[0] = -nx; shift[1] = -1; shift[2] = nx; shift[3] = 1; } else if (graph == 8){ /* && nz == 1: suppressed on 2004-11-18 (side effects?) */ shift[4] = -nx-1; shift[0] = -nx; shift[5] = -nx + 1; shift[1] = -1; shift[3] = 1; /* swapped 3 and 2 on 2007-9-19 */ shift[6] = nx-1; shift[2] = nx; shift[7] = nx + 1; } else if (graph == 6 && nz > 1){ shift[0] = -nx; shift[1] = -1; shift[2] = -(nx * ny); shift[3] = nx; shift[4] = 1; shift[5] = -shift[2]; } else{ (void) sprintf(buf, "set_seq_shift(): invalid parameters\n"); errputstr(buf); return ERROR; } return NO_ERROR; } ERROR_TYPE set_seq_shift(long int nx, long int ny, long int nz, long int graph, long int *shift) { if (graph == 2){ /* added 20110310 for shadow ray processing */ shift[0] = -1; shift[1] = 1; } else if (graph == 4){ /* && nz == 1: suppressed on 2004-11-18 (side effects?) */ shift[0] = -nx; shift[1] = -1; shift[2] = nx; shift[3] = 1; } else if (graph == 8){ /* && nz == 1: suppressed on 2004-11-18 (side effects?) */ shift[0] = -nx; shift[1] = -1; shift[2] = -nx + 1; shift[3] = -nx - 1; shift[4] = 1; shift[5] = nx; shift[6] = nx - 1; shift[7] = nx + 1; } else if (graph == 6 && nz > 1){ shift[0] = -nx; shift[1] = -1; shift[2] = -(nx * ny); shift[3] = nx; shift[4] = 1; shift[5] = -shift[2]; } else if (graph == 18 && nz > 1){ shift[0] = -nx; shift[1] = -1; shift[2] = shift[0] + 1; shift[3] = shift[0] - 1; shift[4] = -(nx * ny); shift[5] = shift[4] + shift[0]; shift[6] = shift[4] - 1; shift[7] = shift[4] + 1; shift[8] = shift[4] - shift[0]; shift[9] = -shift[0]; shift[10] = 1; shift[11] = -shift[2]; shift[12] = -shift[3]; shift[13] = -shift[4]; shift[14] = -shift[5]; shift[15] = -shift[6]; shift[16] = -shift[7]; shift[17] = -shift[8]; } else if (graph == 26 && nz > 1){ shift[0] = -nx; shift[1] = -1; shift[2] = shift[0] + 1; shift[3] = shift[0] - 1; shift[4] = -(nx * ny); shift[5] = shift[4] + shift[0]; shift[6] = shift[4] - 1; shift[7] = shift[4] + 1; shift[8] = shift[4] - shift[0]; shift[9] = shift[5] - 1; shift[10] = shift[5] + 1; shift[11] = shift[8] - 1; shift[12] = shift[8] + 1; shift[13] = -shift[0]; shift[14] = -shift[1]; shift[15] = -shift[2]; shift[16] = -shift[3]; shift[17] = -shift[4]; shift[18] = -shift[5]; shift[19] = -shift[6]; shift[20] = -shift[7]; shift[21] = -shift[8]; shift[22] = -shift[9]; shift[23] = -shift[10]; shift[24] = -shift[11]; shift[25] = -shift[12]; } else{ (void) sprintf(buf, "set_seq_shift(): invalid parameters\n"); errputstr(buf); return ERROR; } return NO_ERROR; } ERROR_TYPE setinvseqshift(long int nx, long int ny, long int nz, long int graph, long int *shft) { if (graph == 4 && nz == 1){ shft[2] = -nx; shft[3] = -1; shft[0] = nx; shft[1] = 1; } else if (graph == 8 && nz == 1){ shft[5] = -nx; shft[4] = -1; shft[6] = -nx + 1; shft[7] = -nx - 1; shft[1] = 1; shft[0] = nx; shft[2] = nx - 1; shft[3] = nx + 1; } else if (graph == 6 && nz > 1){ shft[3] = -nx; shft[4] = -1; shft[2] = nx * ny; shft[0] = nx; shft[1] = 1; shft[5] = -shft[2]; } else if (graph == 18 && nz > 1){ shft[9] = -nx; shft[10] = -1; shft[11] = shft[9] + 1; shft[12] = shft[9] - 1; shft[13] = -(nx * ny); shft[14] = shft[13] + shft[9]; shft[15] = shft[13] - 1; shft[16] = shft[13] + 1; shft[17] = shft[13] - shft[9]; shft[0] = -shft[9]; shft[1] = 1; shft[2] = -shft[11]; shft[3] = -shft[12]; shft[4] = -shft[13]; shft[5] = -shft[14]; shft[6] = -shft[15]; shft[7] = -shft[16]; shft[8] = -shft[17]; } else if (graph == 26 && nz > 1){ shft[13] = -nx; shft[14] = -1; shft[15] = shft[13] + 1; shft[16] = shft[13] - 1; shft[17] = -(nx * ny); shft[18] = shft[17] + shft[13]; shft[19] = shft[17] - 1; shft[20] = shft[17] + 1; shft[21] = shft[17] - shft[13]; shft[22] = shft[18] - 1; shft[23] = shft[18] + 1; shft[24] = shft[21] - 1; shft[25] = shft[21] + 1; shft[0] = -shft[13]; shft[1] = -shft[14]; shft[2] = -shft[15]; shft[3] = -shft[16]; shft[4] = -shft[17]; shft[5] = -shft[18]; shft[6] = -shft[19]; shft[7] = -shft[20]; shft[8] = -shft[21]; shft[9] = -shft[22]; shft[10] = -shft[23]; shft[11] = -shft[24]; shft[12] = -shft[25]; } else return ERROR; return NO_ERROR; } void set_shift_and_box(unsigned char *im1, int *box, long int x, long int y, long int *shift) { long int i, j, k; long int cnt = 0; long int nx, ny, nz, ox, oy, oz; nx = box[0]; ny = box[1]; nz = box[2]; ox = box[3]; oy = box[4]; oz = box[5]; for (i = 0; i < nz; i++){ for (j = 0; j < ny; j++){ for (k = 0; k < nx; k++){ if (*im1){ shift[cnt] = k - ox + x * (j - oy) + x * y * (i - oz); cnt++; } im1++; } } } if (ox < 0) box[0] = 0; else box[0] = ox; if (ox >= nx) box[1] = 0; else box[1] = nx - 1 - ox; if (oy < 0) box[2] = 0; else box[2] = oy; if (oy >= ny) box[3] = 0; else box[3] = ny - 1 - oy; if (oz < 0) box[4] = 0; else box[4] = oz; if (oz >= nz) box[5] = 0; else box[5] = nz - 1 - oz; } void set_shift_and_box_and_weight(unsigned char *im1, MIALFLOAT *im2, int *box, long int x, long int y, long int *shift, MIALFLOAT *weight) { long int i, j, k; long int cnt = 0; long int nx, ny, nz, ox, oy, oz; nx = box[0]; ny = box[1]; nz = box[2]; ox = box[3]; oy = box[4]; oz = box[5]; for (i = 0; i < nz; i++){ for (j = 0; j < ny; j++){ for (k = 0; k < nx; k++){ if (*im1){ shift[cnt] = k - ox + x * (j - oy) + x * y * (i - oz); weight[cnt] = *im2; cnt++; } im1++; im2++; } } } if (ox < 0) box[0] = 0; else box[0] = ox; if (ox >= nx) box[1] = 0; else box[1] = nx - 1 - ox; if (oy < 0) box[2] = 0; else box[2] = oy; if (oy >= ny) box[3] = 0; else box[3] = ny - 1 - oy; if (oz < 0) box[4] = 0; else box[4] = oz; if (oz >= nz) box[5] = 0; else box[5] = nz - 1 - oz; } void uc_set_shift_and_box_and_weight(unsigned char *im1, UCHAR *im2, int *box, long int x, long int y, long int *shift, UCHAR *weight) { long int i, j, k; long int cnt = 0; long int nx, ny, nz, ox, oy, oz; nx = box[0]; ny = box[1]; nz = box[2]; ox = box[3]; oy = box[4]; oz = box[5]; for (i = 0; i < nz; i++){ for (j = 0; j < ny; j++){ for (k = 0; k < nx; k++){ if (*im1){ shift[cnt] = k - ox + x * (j - oy) + x * y * (i - oz); weight[cnt] = *im2; cnt++; } im1++; im2++; } } } if (ox < 0) box[0] = 0; else box[0] = ox; if (ox >= nx) box[1] = 0; else box[1] = nx - 1 - ox; if (oy < 0) box[2] = 0; else box[2] = oy; if (oy >= ny) box[3] = 0; else box[3] = ny - 1 - oy; if (oz < 0) box[4] = 0; else box[4] = oz; if (oz >= nz) box[5] = 0; else box[5] = nz - 1 - oz; } void transpose(shift, n) long int *shift; long int n; { long int i; for (i = 0; i < n; i++) shift[i] *= -1; } long int objectpix(IMAGE *im) { long int i, n=0; long int npix = GetImNPix(im); UCHAR *p = (UCHAR *)GetImPtr(im); if (GetImDataType(im)!=t_UCHAR){ (void)sprintf(buf,"objectpix(im): im must be of type uint8 !\n"); errputstr(buf); return 0; } for (i=0; i. ***********************************************************************/ #include #include "miallib.h" #ifdef OPENMP #include #endif /** \addtogroup group_dem * @{ */ /* ** Function to shade an input image. ** Reference: R. Sternberg (1986) Grayscale morphology. CVGIP, 35, 333-355. */ extern int histcompress(IMAGE *); #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_shade(IMAGE *im, int dir) { /* ** im: input image ** dir: direction of light: 0 1 2 ** 7 . 3 ** 6 5 4 */ PIX_TYPE *p1; INT32 *p2, *pfin, min; int shift, nx, box[6]; IMAGE *itmp; nx = GetImNx(im); switch (dir){ /* Set shift, taking dir into account */ case 0: shift = -nx - 1; break; case 1: shift = -nx; break; case 2: shift = -nx + 1; break; case 3: shift = 1; break; case 4: shift = nx + 1; break; case 5: shift = nx; break; case 6: shift = nx - 1; break; case 7: shift = -1; break; default: (void) printf("shade(): invalid direction\n"); return NULL; } itmp = (IMAGE *)create_image(t_INT32, nx, GetImNy(im), GetImNz(im)); if (itmp==NULL) return(NULL); /* Here we go */ p1 = (PIX_TYPE *)GetImPtr(im) + nx + 1; p2 = (INT32 *)GetImPtr(itmp) + nx + 1; pfin = p2 + nx*GetImNy(im)-nx-1; min = *p1 - *(p1 + shift); for (; p2 < pfin; p1++, p2++){ *p2 = *p1 - *(p1 + shift); if (min > *p2) min = *p2; } p2 = (INT32 *)GetImPtr(itmp) + nx + 1; for (; p2 < pfin; p2++) *p2 -= min; BOX_2D; i32_framebox(itmp,box,0L); (void) histcompress(itmp); /* imout=(IMAGE *)to_uchar(itmp); */ /* free_image(itmp); */ /* return(imout); */ to_uchar(itmp); return(itmp); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" IMAGE *us_shade(IMAGE *im, int dir) { /* ** im: input image ** dir: direction of light: 0 1 2 ** 7 . 3 ** 6 5 4 */ PIX_TYPE *p1; INT32 *p2, *pfin, min; int shift, nx, box[6]; IMAGE *itmp; nx = GetImNx(im); switch (dir){ /* Set shift, taking dir into account */ case 0: shift = -nx - 1; break; case 1: shift = -nx; break; case 2: shift = -nx + 1; break; case 3: shift = 1; break; case 4: shift = nx + 1; break; case 5: shift = nx; break; case 6: shift = nx - 1; break; case 7: shift = -1; break; default: (void) printf("shade(): invalid direction\n"); return NULL; } itmp = (IMAGE *)create_image(t_INT32, nx, GetImNy(im), GetImNz(im)); if (itmp==NULL) return(NULL); /* Here we go */ p1 = (PIX_TYPE *)GetImPtr(im) + nx + 1; p2 = (INT32 *)GetImPtr(itmp) + nx + 1; pfin = p2 + nx*GetImNy(im)-nx-1; min = *p1 - *(p1 + shift); for (; p2 < pfin; p1++, p2++){ *p2 = *p1 - *(p1 + shift); if (min > *p2) min = *p2; } p2 = (INT32 *)GetImPtr(itmp) + nx + 1; for (; p2 < pfin; p2++) *p2 -= min; BOX_2D; i32_framebox(itmp,box,0L); (void) histcompress(itmp); /* imout=(IMAGE *)to_uchar(itmp); */ /* free_image(itmp); */ /* return(imout); */ to_uchar(itmp); return(itmp); } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_shade(IMAGE *im, int dir) { /* ** im: input image ** dir: direction of light: 0 1 2 ** 7 . 3 ** 6 5 4 */ PIX_TYPE *p1; INT32 *p2, *pfin, min; int shift, nx, box[6]; IMAGE *itmp; nx = GetImNx(im); switch (dir){ /* Set shift, taking dir into account */ case 0: shift = -nx - 1; break; case 1: shift = -nx; break; case 2: shift = -nx + 1; break; case 3: shift = 1; break; case 4: shift = nx + 1; break; case 5: shift = nx; break; case 6: shift = nx - 1; break; case 7: shift = -1; break; default: (void) printf("shade(): invalid direction\n"); return NULL; } itmp = (IMAGE *)create_image(t_INT32, nx, GetImNy(im), GetImNz(im)); if (itmp==NULL) return(NULL); /* Here we go */ p1 = (PIX_TYPE *)GetImPtr(im) + nx + 1; p2 = (INT32 *)GetImPtr(itmp) + nx + 1; pfin = p2 + nx*GetImNy(im)-nx-1; min = *p1 - *(p1 + shift); for (; p2 < pfin; p1++, p2++){ *p2 = *p1 - *(p1 + shift); if (min > *p2) min = *p2; } p2 = (INT32 *)GetImPtr(itmp) + nx + 1; for (; p2 < pfin; p2++) *p2 -= min; BOX_2D; i32_framebox(itmp,box,0L); (void) histcompress(itmp); /* imout=(IMAGE *)to_uchar(itmp); */ /* free_image(itmp); */ /* return(imout); */ to_uchar(itmp); return(itmp); } #include "i32_undef.h" IMAGE *shade(IMAGE *im, int dir) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_shade(im, dir)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_volume(im)); break; #endif case t_USHORT: return(us_shade(im, dir)); break; case t_INT32: return(i32_shade(im, dir)); break; default: (void)sprintf(buf,"WARNING in shade(im, dir): invalid pixel type\n"); errputstr(buf); } return(NULL); } #include "us_def.h" IMAGE *us_LineDilate3D(IMAGE *im, float dh) { /* simple function to produce the closing by 3D half line and slope equal to dh. This closing comes down to a dilation that the line segment has an infinite length. The idea is to use this function to produce the topography-induced shadow volume of a DEM with arbitrary illumination parameters. The DEM is rotated beforeand to achieve horizontal dilations only, from left to right. The shadowed volume is simply obtained by performing the top-hat by closing and the binary shadow mask corresponds to the non-zero values. Actual masks are simply obtained by applying the backward rotation. by Pierre Soille First: 20141203 First working: 20141203 TODO: adapt processing along arbitrary line segments to avoid rotation. */ PIX_TYPE *pi, *picrt, a; IMAGE *imout; MIALFLOAT *po, *pocrt, b; int i, j, nx, ny; nx=GetImNx(im); ny=GetImNy(im); imout=(IMAGE *)create_image(t_MIALFLOAT, nx, ny, 1); if (imout==NULL) return NULL; po=(MIALFLOAT *)GetImPtr(imout); pi=(PIX_TYPE *)GetImPtr(im); printf("dh=%f\n", dh); #pragma omp parallel for private(j,picrt,pocrt,i,a,b) for(j=0; j. ***********************************************************************/ /** * @file shm.c * @author Pierre SOILLE * @date Wed Sep 25 14:30:49 2013 * * @details * * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include "miallib.h" /** \addtogroup group_mem * @{ */ /* ** inspired by ** http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/apis/apiexusmem.htm ** https://www.ibm.com/support/knowledgecenter/ssw_i5_54/apiref/apiexusmem.htm ** ** use shell command ipcs to monitor shared memory segments ** ** first: 20130925 ** ** by Pierre Soille */ IMAGE *shmatimage(key_t shmkey, size_t nx, size_t ny, size_t nz, size_t nbyte, int type) { void *shm_address; int shmid; size_t bpp; IMAGE *im; switch(type){ case t_UCHAR: bpp=1; break; case t_USHORT: case t_SHORT: bpp=2; break; case t_UINT32: case t_INT32: case t_FLOAT: bpp=4; break; case t_DOUBLE: bpp=8; break; default: printf("shmatimage(): invalid type(=%d), detaching shared memory ...\n", type); return NULL; } if(nbytenx*ny*nz*bpp) printf("shmatimage(): warning, nbyte is larger than nx*ny*nz*bpp. Assuming padding at the start of shared memory\n"); SetImNByte(im,nx*ny*nz*bpp); SetImPtr(im, (char *)shm_address+nbyte-nx*ny*nz*bpp); SetImNx(im,nx); SetImNy(im,ny); SetImNz(im,nz); return im; } ERROR_TYPE shmdtimage(void *shm_address, int semkey_flag, key_t semkey) { void *sem_address; int semid; int rc; /* Detach the shared memory segment from the current process. */ rc = shmdt(shm_address); if (rc==-1) { printf("shdtimage(): shmdt() failed\n"); return -1; } /* if semkey_flag !=0 */ /* Get the already created shared memory ID associated with key. */ /* If the shared memory ID does not exist, then it will not be */ /* created, and an error will occur. */ if (semkey_flag){ semid = shmget(semkey,sizeof(sem_t), 0666); if (semid == -1){ printf("shmdtimage(): shmget() failed for semkey\n"); return ERROR; } /* Attach the shared memory segment of semaphore to the client process */ sem_address = (sem_t*) shmat(semid, NULL, 0); if ( sem_address==NULL ){ printf("shmatimage(): shmat() failed\n"); return ERROR; } rc=sem_post(sem_address); if (rc == -1){ printf("sem_post(): sem_post() failed\n"); return -1; } } return NO_ERROR; } /* unused code at the moment, based on *named* semaphores */ #define NUMSEMS 2 IMAGE *shmatimage_named_semaphores(key_t semkey, key_t shmkey, size_t nx, size_t ny, size_t nz, size_t nbyte, int type) { struct sembuf operations[2]; void *shm_address; int semid, shmid, rc; IMAGE *im; /* Get the already created semaphore ID associated with key. */ /* If the semaphore set does not exist, then it will not be */ /* created, and an error will occur. */ semid = semget( semkey, NUMSEMS, 0666); if ( semid == -1 ){ printf("shmatimage: semget() failed\n"); return NULL; } /* Get the already created shared memory ID associated with key. */ /* If the shared memory ID does not exist, then it will not be */ /* created, and an error will occur. */ shmid = shmget(shmkey, nbyte, 0666); if (shmid == -1){ printf("main: shmget() failed\n"); return NULL; } /* Attach the shared memory segment to the client process. */ shm_address = shmat(shmid, NULL, 0); if ( shm_address==NULL ){ printf("shmatimage: shmat() failed\n"); return NULL; } /* First, check to see if the first semaphore is a zero. If it */ /* is not, it is busy right now. The semop() command will wait */ /* for the semaphore to reach zero before running the semop(). */ /* When it is zero, increment the first semaphore to show that */ /* the shared memory segment is busy. */ operations[0].sem_num = 0; /* Operate on the first sem */ operations[0].sem_op = 0; /* Wait for the value to be=0 */ operations[0].sem_flg = 0; /* Allow a wait to occur */ operations[1].sem_num = 0; /* Operate on the first sem */ operations[1].sem_op = 1; /* Increment the semval by one */ operations[1].sem_flg = 0; /* Allow a wait to occur */ rc = semop( semid, operations, 2 ); if (rc == -1){ printf("shmatimage: semop() failed\n"); return NULL; } im = (IMAGE *)calloc((size_t)1, sizeof(IMAGE)); SetImDataType(im, type); SetImNByte(im,nbyte); SetImPtr(im,shm_address); SetImNx(im,nx); SetImNy(im,ny); SetImNz(im,nz); return im; } ERROR_TYPE shmdtimage_named_semaphores(key_t semkey, void *shm_address) { struct sembuf operations[2]; int semid; int rc; /* Release the shared memory segment by decrementing the in-use */ /* semaphore (the first one). Increment the second semaphore to */ /* show that the client is finished with it. */ operations[0].sem_num = 0; /* Operate on the first sem */ operations[0].sem_op = -1; /* Decrement the semval by one */ operations[0].sem_flg = 0; /* Allow a wait to occur */ operations[1].sem_num = 1; /* Operate on the second sem */ operations[1].sem_op = 1; /* Increment the semval by one */ operations[1].sem_flg = 0; /* Allow a wait to occur */ /* Get the already created semaphore ID associated with key. */ /* If the semaphore set does not exist, then it will not be */ /* created, and an error will occur. */ semid = semget( semkey, NUMSEMS, 0666); if ( semid == -1 ){ printf("shmdtimage: semget() failed\n"); return -1; } rc = semop( semid, operations, 2 ); if (rc == -1) { printf("shdtimage: semop() failed\n"); return -1; } /* Detach the shared memory segment from the current process. */ rc = shmdt(shm_address); if (rc==-1) { sprintf(buf, "shdtimage: shmdt() failed\n"); errputstr(buf); return -1; } return NO_ERROR; } /*@}*/ jeolib-miallib-1.1.6/core/c/simplifyLine.c000066400000000000000000000076651467232417700204070ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** simplifyLine.c - description ------------------- begin : Wed Jun 16 2004 ***************************************************************************/ #include #include #define NO_BUF #include "simplifyLine.h" extern struct LINE * getLine(struct LINEPOOL * linepool, int startX, int startY, int middleX, int middleY, int endX, int endY); /* * isPointAtImageCorner: caculates whether the point is one of the four corner points of the image * * Parameters: * * point point to the point * * width width of image * * height height of image * * Return values: * * 0 if point is no corner point of the image * * 1 if point is corner point of the image */ int isPointAtImageCorner(struct POINT * point, int width, int height) { //top left if((point->x == 0) && (point->y == 0)){ return 1; } //top right if((point->x == width) && (point->y == 0)){ return 1; } //bottom right if((point->x == width+0) && (point->y == height+0)){ return 1; } //bottom left if((point->x == 0) && (point->y == height+0)){ return 1; } return 0; } /* * simplifyLine: make a simplification of the exact boundary line segments stored in the linepool * * Parameters: * * linepool pointer to the linepool, where all boundary line segments are stored * * tolerance parameter for the simplification of the line segments. The higher the value * the more will the line segments be simplified * * width width of image (neded to determine which points are corner points of the image) * * height height of image (neded to determine which points are corner points of the image) * * Return values: * * none */ void simplifyLine(struct LINEPOOL * linepool, double tolerance, int width, int height) { int i,j; double * pointsX, * pointsY; int * useFlags, pointCount; struct LINE * line; struct POINT * point; for(i=0; i< linepool->crtPos; i++){ line = linepool->lines[i]; pointCount = line->crtPos; if(isLineSegmentClosed(line)){ pointCount--; } pointsX = (double *) calloc(sizeof(double), pointCount); pointsY = (double *) calloc(sizeof(double), pointCount); useFlags = (int *) calloc(sizeof(int), pointCount); //prepare arrays with point information for(j=0; jpoints[j]; pointsX[j]=point->x; pointsY[j]=point->y; useFlags[j]=0; } ReducePoints(pointsX, pointsY, pointCount, useFlags, tolerance); //update information in linepool with informations from ReducePoints for(j=0; jpoints[j]; point->useFlag=useFlags[j]; if(isPointAtImageCorner(point, width, height)){ point->useFlag=1; } } if(isLineSegmentClosed(line)){ line->points[j]->useFlag=1; } free(pointsX); free(pointsY); free(useFlags); } } jeolib-miallib-1.1.6/core/c/simplifyLine.h000066400000000000000000000026741467232417700204070ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** simplifyLine.h - description ------------------- begin : Wed Jun 16 2004 ***************************************************************************/ #ifndef init_simplifyLine #define init_simplifyLine #include "douglas-peucker.h" #include "borderdetection.h" int isPointAtImageCorner(struct POINT * point, int width, int height); void simplifyLine(struct LINEPOOL * linepool, double tolerance, int width, int height); #endif jeolib-miallib-1.1.6/core/c/skel.c000066400000000000000000000636461467232417700167020ustar00rootroot00000000000000/*********************************************************************** Author(s): Marcin Iwanowski and Pierre Soille Copyright (C) 2005-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file skel.c * * @date * * @details see also \cite iwanowski-soille2005caip1 * */ #include #include #include #include "miallib.h" #include "fifo.h" #include "uc_def.h" /** \addtogroup group_hmtsk * @{ */ /* binary skeletonizaton procedures from august 2005 last modification 17.08.05 - Marcin Iwanowski */ /* replace all addframebox by framebox and commented all subframebox calls on 3/5/2006 Pierre */ void getngbshift8 (int shift[9],int nx) { /* neighbor shift */ shift[0] = -1; /* 4 connected ngbs */ shift[1] = 1; shift[2] = -nx; shift[3] = nx; shift[4] = -nx-1; /* 8 connected ngbs */ shift[5] = nx-1; shift[6] = -nx+1; shift[7] = nx+1; shift[8] = 0; /* central point */ } int simple_pixel (PIX_TYPE *pimg, int stype, long int pos, int nx) { int code; int htab[6][256] ={ /* simple g=8, g'=4 */ { 0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,\ 1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,\ 1,1,0,0,0,1,0,1,1,1,1,1,0,1,1,0,\ 0,1,0,0,0,1,0,1,0,1,0,1,0,1,1,0,\ 1,0,1,0,1,1,1,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,1,1,1,1,0,0,0,1,0,1,1,0,\ 0,0,0,0,0,1,0,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,\ 1,0,1,0,0,0,1,1,1,1,1,1,0,1,1,0,\ 0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,\ 0,0,1,0,0,0,1,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0 }, /* simple g=4, g'=8 */ { 0,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,\ 0,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,\ 0,1,1,0,1,0,0,0,1,1,0,0,0,0,0,0,\ 0,1,1,0,1,1,0,0,1,1,0,0,0,1,0,0,\ 0,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,\ 0,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,\ 0,1,1,0,1,0,1,0,1,1,0,0,0,0,0,0,\ 0,1,1,0,1,1,1,1,1,1,0,0,0,1,0,1,\ 0,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,\ 0,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,\ 0,1,1,0,1,0,0,0,1,1,1,1,0,0,0,0,\ 0,1,1,0,1,1,0,0,1,1,1,1,0,1,0,1,\ 0,1,1,0,1,0,1,0,1,0,1,0,0,0,1,0,\ 0,1,1,0,1,1,1,1,1,0,1,0,0,0,1,1,\ 0,1,1,0,1,0,1,0,1,1,1,1,0,0,1,1,\ 0,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0 }, /* simple g=4, g'=4 Ronse's {4,8}*/ { 0,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,\ 0,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\ 0,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,\ 0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,\ 0,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,\ 0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,\ 0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,\ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,\ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,\ 0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0 }, /* w-simple g=8, g'=4;*/ { 1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0,\ 1,1,0,0,1,1,1,1,0,1,0,1,0,1,1,0,\ 1,1,0,0,0,1,0,1,1,1,1,1,0,1,1,0,\ 0,1,0,0,0,1,0,1,0,1,0,1,0,1,1,0,\ 1,0,1,0,1,1,1,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,1,1,1,1,0,0,0,1,0,1,1,0,\ 0,0,0,0,0,1,0,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,1,0,1,0,0,0,1,0,1,1,0,\ 1,0,1,0,0,0,1,1,1,1,1,1,0,1,1,0,\ 0,0,0,0,0,0,1,1,0,1,0,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,1,0,1,0,1,1,0,\ 0,0,1,0,0,0,1,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,0,1,1,0,0,0,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,0,1,1,0,1,1,0,\ 0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0 }, /* w-simple g=4, g'=8 */ { 1,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,\ 1,1,1,0,1,1,0,0,1,0,0,0,0,0,0,0,\ 1,1,1,0,1,0,0,0,1,1,0,0,0,0,0,0,\ 1,1,1,0,1,1,0,0,1,1,0,0,0,1,0,0,\ 1,1,1,0,1,0,1,0,1,0,0,0,0,0,0,0,\ 1,1,1,0,1,1,1,1,1,0,0,0,0,0,0,0,\ 1,1,1,0,1,0,1,0,1,1,0,0,0,0,0,0,\ 1,1,1,0,1,1,1,1,1,1,0,0,0,1,0,1,\ 1,1,1,0,1,0,0,0,1,0,1,0,0,0,0,0,\ 1,1,1,0,1,1,0,0,1,0,1,0,0,0,0,0,\ 1,1,1,0,1,0,0,0,1,1,1,1,0,0,0,0,\ 1,1,1,0,1,1,0,0,1,1,1,1,0,1,0,1,\ 1,1,1,0,1,0,1,0,1,0,1,0,0,0,1,0,\ 1,1,1,0,1,1,1,1,1,0,1,0,0,0,1,1,\ 1,1,1,0,1,0,1,0,1,1,1,1,0,0,1,1,\ 1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,0 }, /* w-simple g=4, g'=4 Ronse's {4,8}*/ { 1,1,1,0,1,0,0,0,1,0,0,0,0,0,0,0,\ 1,1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,\ 1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,\ 0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,\ 1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,\ 1,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\ 0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,\ 0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,\ 0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,\ 0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,0,\ 0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,\ 0,0,0,0,0,0,0,1,0,0,0,1,0,1,1,0 }}; code = 0; if (*(pimg+pos)>0) { code = (*(pimg+pos-1) == 1); code |= (*(pimg+pos+1) == 1) <<1; code |= (*(pimg+pos-nx) == 1) <<2; code |= (*(pimg+pos+nx) == 1) <<3; code |= (*(pimg+pos-nx-1) == 1) <<4; code |= (*(pimg+pos+nx-1) == 1) <<5; code |= (*(pimg+pos-nx+1) == 1) <<6; code |= (*(pimg+pos+nx+1) == 1) <<7; return (htab[stype][code]); /* returns 1 if point on position 'pos' at level refval of image pointed by '*pimg' is simple, 0 - otherwise */ } else return 0; } int test_anchor (PIX_TYPE *panchor, int atype, long int pos) { return ((atype == 0) || (*(panchor + pos)==0)); /* atype == 0 - we are not using anchor pixels (return 1) == 1 we use them and return 1 if anchor pixel at pos does not exist */ } ERROR_TYPE binODthin_noqueue(IMAGE *imin, int stype, int atype, IMAGE *imanchor) /* binary order-dependent thinning non-queue version */ /* stype == 0 simple g=8, g'=4 == 1 simple g=4, g'=8 == 2 simple g=4, g'=4 Ronse's {4,8} == 3 simple g=8, g'=4 == 4 simple g=4, g'=8 == 5 simple g=4, g'=4 Ronse's {4,8} atype == 0 anchor pixels are not considered (*imanchor not used) == 1 anchor pixels considered (*imanchor used) */ { long int i, npix, startindoff, endindoff; int nx; // int kk=0; IMAGE *isimple; PIX_TYPE *pimin, *pimanchor=NULL, *psimple; int deleted = 1; int sh[9]; // int counter = 0; int box[6]={2,2,2,2,0,0}; if (GetImDataType(imin) != t_UCHAR){ (void)sprintf(buf,"wrong input data type !! \n"); errputstr(buf); return ERROR; } if (atype == 1){ if ( (GetImNx(imanchor) != GetImNx(imin)) || (GetImNy(imanchor) != GetImNy(imin)) ) { (void)sprintf(buf,"input and anchor images have different sizes !! \n"); errputstr(buf); return ERROR; } if (GetImDataType(imanchor) != t_UCHAR){ (void)sprintf(buf,"wrong input data type !! \n"); errputstr(buf); return ERROR; } generic_framebox(imanchor,box,0); pimanchor = (PIX_TYPE *)GetImPtr(imanchor); } generic_framebox(imin,box,0); nx = GetImNx(imin); npix = GetImNPix(imin); startindoff = 2*nx + 2 ; /* start offset (skip the first two lines (of enlarged image) and the first point of the second) */ endindoff = npix - 2*nx - 2 ; /* end offset (finish one pixel before the end of the second line before last */ pimin = (PIX_TYPE *)GetImPtr(imin); isimple = create_image(GetImDataType(imin), nx , GetImNy(imin) , GetImNz(imin)); if (isimple == NULL){ (void)sprintf(buf,"not enough memory for temporary image\n"); errputstr(buf); return(ERROR); } psimple = (PIX_TYPE *)GetImPtr(isimple); getngbshift8(sh,nx); deleted=1; while (deleted){ deleted = 0; // counter = 0; for (i=startindoff; i= *(pimg + pos)); code |= (*(pimg + pos + *c) >= *(pimg + pos))<<1; code |= (*(pimg + pos + *b) >= *(pimg + pos))<<2; code |= (*(pimg + pos + *a) >= *(pimg + pos))<<3; *conftype = code + 5; return (simple_pair4[stype][code]); } else { /* diagonal neighbor */ switch (ngbpos) { case 4: *a = sh[0] ; *b = sh[2] ; break; case 5: *a = sh[3] ; *b = sh[0] ; break; case 6: *a = sh[2] ; *b = sh[1] ; break; case 7: *a = sh[1] ; *b = sh[3] ; break; } code = (*(pimg + pos + *b) >= *(pimg + pos)); code |= (*(pimg + pos + *a) >= *(pimg + pos))<<1; *conftype = code + 1; return (simple_pair2[stype][code]); } } int num_sngb (PIX_TYPE *pimg, long int pos, int *sh, int ngbnum) { /* returns the number of ngbs higher-equal than a given pixel */ int i, sum=0; for (i=0; i= *(pimg + pos)) sum ++; return sum; } int testsimple (PIX_TYPE *pimg, PIX_TYPE *pimanchor, int atype, int stype, long int pos, int ngbp, int *sh, int nx) { if ((test_anchor(pimanchor,atype,pos + ngbp)) && (simple_pixel(pimg,stype,pos + ngbp,nx)) && (*(pimg + pos) == *(pimg + pos + ngbp) )) return 1; else return 0; } int indep_simple (PIX_TYPE *pimg, PIX_TYPE *pimanchor, int stype, int atype, long int pos, int *sh, int nx) { int i; int allindep = 1; int ngbnum = 0; int a,b,c,d,aa=0,bb=0; int ct=0; int conftype, founddiff, zerocount; for (i=0; i<8 && allindep ; i++) if (testsimple (pimg, pimanchor, atype, stype, pos, sh[i], sh, nx)) { ngbnum ++; if (simple_pair(pimg, stype, pos, i, sh, &conftype,&a,&b,&c,&d) == 0) {allindep = 0; aa=a; bb=b; ct = conftype; } } if (allindep){ct = conftype;} if ((allindep == 0) && ((stype == 1) || (stype == 2) || (stype == 4) || (stype == 5) )) { if (ct == 4) /* check edge configuration*/ if ((testsimple (pimg, pimanchor, atype, stype, pos, aa, sh, nx)) && (testsimple (pimg, pimanchor, atype, stype, pos, bb, sh, nx)) ) { zerocount = 0; for (i=0; i<4; i++) if (*(pimg + pos + sh[i]) < *(pimg + pos)) zerocount ++; if (zerocount == 2) { allindep = 1; /* for wshed OK for skel, check isolated quad */ if (stype < 3) { founddiff = 0; for (i=0; i<4 && (founddiff == 0); i++) if (testsimple (pimg, pimanchor, atype, stype, pos, sh[i], sh, nx)) { if (num_sngb (pimg, pos + sh[i],sh,4) != 2) founddiff = 1; // one simple ngb don't have 3 4-ngb's } if (founddiff == 0) allindep=0; } } } return allindep; } if ((allindep == 1) && (stype<3) ) // is independent from all simple neighbors { // check whether p belongs to a triple or quadruple of isolated simple pixels if ( ( (ngbnum == 2) && ((ct == 2) || (ct == 3) || (ct == 6) || (ct == 7) || (ct == 9) || (ct == 13)) ) || ( (ngbnum == 3) && ((ct == 4) || (ct == 8) || (ct == 17)) ) ) { founddiff = 0; for (i=0; i<8 && (founddiff == 0); i++) if (testsimple (pimg, pimanchor, atype, stype, pos, sh[i], sh, nx)) { if (num_sngb (pimg, pos + sh[i],sh,8) != ngbnum) founddiff = 1; // one simple ngb has different number of ngs's than p - bad } if (founddiff == 0) allindep=0; } } return allindep; } ERROR_TYPE binOIthin_noqueue (IMAGE *imin, int stype, int atype, IMAGE *imanchor) /* anchored graytone order-dependent skeleton */ /* stype == 0 simple g=8, g'=4 == 1 simple g=4, g'=8 == 2 simple g=4, g'=4 Ronse's {4,8} == 3 simple g=8, g'=4 == 4 simple g=4, g'=8 == 5 simple g=4, g'=4 Ronse's {4,8} atype == 0 anchor pixels are not considered (*imanchor not used) == 1 anchor pixels considered (*imanchor used) */ { long int i,npix,startindoff,endindoff; // int kk=0; IMAGE *isimple; PIX_TYPE *pimin, *pimanchor=NULL, *psimple; int nx; int deleted = 1; int sh[9]; //int counter = 0; int box[6]={2,2,2,2,0,0}; if (GetImDataType(imin) != t_UCHAR){ (void)sprintf(buf,"wrong input data type !! \n"); errputstr(buf); return ERROR; } if (atype == 1) /* check only if anchor image is used */ { if ( (GetImNx(imanchor) != GetImNx(imin)) || (GetImNy(imanchor) != GetImNy(imin)) ) { (void)sprintf(buf,"input and anchor images have different sizes !! \n"); errputstr(buf); return ERROR; } generic_framebox(imanchor,box,0); pimanchor = (PIX_TYPE *)GetImPtr(imanchor); } generic_framebox(imin,box,0); nx = GetImNx(imin); npix = GetImNPix(imin); startindoff = 2*nx + 2 ; /* start offset (skip the first two lines (of enlarged image) and the first point of the second) */ endindoff = npix - 2*nx - 2 ; /* end offset (finish one pixel before the end of the second line before last */ pimin = (PIX_TYPE *)GetImPtr(imin); isimple = create_image ( GetImDataType(imin), nx , GetImNy(imin) , GetImNz(imin)); if (isimple == NULL) { (void)sprintf(buf,"not enough memory for temporary image\n"); errputstr(buf); return(ERROR); } psimple = (PIX_TYPE *)GetImPtr(isimple); getngbshift8(sh,nx); deleted=1;//kk=0; while (deleted) { deleted = 0; //counter = 0; for (i=startindoff; i. ***********************************************************************/ #include #include #include "miallib.h" /** @defgroup group_hmtsk Hit-or-miss and skeletons * Functions dealing with hit-or-miss and skeletonisation. * @{ */ /* ** Grey level skeleton with thinnings (1988). */ #include "uc_def.h" ERROR_TYPE uc_skeleton(IMAGE *im) { IMAGE *i0; long int shft[9], shft_0[9], shft_1[9], k; PIX_TYPE *p1, *p2, *ptmp, ero, dil; PIX_TYPE *pfin, val; int n, idpt; int na0=0, na1=0; int nx=GetImNx(im); i0 = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (i0==NULL) return(ERROR); shft[0]= -nx-1; shft[1]=shft[0]+1; shft[2]=shft[1]+1; shft[3]= -1; shft[4] = 0; shft[5]=1; shft[6]= nx-1; shft[7]=shft[6]+1; shft[8]=shft[7]+1; /* here we go */ do{ idpt = TRUE; for (n = 0; n < 8; n++){ switch(n) { /* case 0 to 7 ==> homotopic thinning */ case 0 : na1 = 4; na0 = 3; shft_0[0] = shft[0]; shft_0[1] = shft[1]; /* 0 0 0 */ shft_0[2] = shft[2]; /* . 1 . */ shft_1[0] = shft[4]; shft_1[1] = shft[6]; /* 1 1 1 */ shft_1[2] = shft[7]; shft_1[3] = shft[8]; break; case 1 : na1 = 4; na0 = 3; shft_0[0] = shft[2]; shft_0[1] = shft[5]; shft_0[2] = shft[8]; shft_1[0] = shft[0]; shft_1[1] = shft[3]; shft_1[2] = shft[4]; shft_1[3] = shft[6]; break; case 2 : na1 = 4; na0 = 3; shft_0[0] = shft[6]; shft_0[1] = shft[7]; shft_0[2] = shft[8]; shft_1[0] = shft[0]; shft_1[1] = shft[1]; shft_1[2] = shft[2]; shft_1[3] = shft[4]; break; case 3 : na1 = 4; na0 = 3; shft_0[0] = shft[0]; shft_0[1] = shft[3]; shft_0[2] = shft[6]; shft_1[0] = shft[2]; shft_1[1] = shft[4]; shft_1[2] = shft[5]; shft_1[3] = shft[8]; break; case 4 : na1 = 4; na0 = 2; shft_0[0] = shft[1]; shft_0[1] = shft[5]; /* . 0 . */ shft_1[0] = shft[3]; shft_1[1] = shft[4]; /* 1 1 0 */ shft_1[2] = shft[6]; shft_1[3] = shft[7]; /* 1 1 . */ break; case 5 : na1 = 4; na0 = 2; shft_0[0] = shft[5]; shft_0[1] = shft[7]; shft_1[0] = shft[0]; shft_1[1] = shft[1]; shft_1[2] = shft[3]; shft_1[3] = shft[4]; break; case 6 : na1 = 4; na0 = 2; shft_0[0] = shft[3]; shft_0[1] = shft[7]; shft_1[0] = shft[1]; shft_1[1] = shft[2]; shft_1[2] = shft[4]; shft_1[3] = shft[5]; break; case 7 : na1 = 4; na0 = 2; shft_0[0] = shft[1]; shft_0[1] = shft[3]; shft_1[0] = shft[4]; shft_1[1] = shft[5]; shft_1[2] = shft[7]; shft_1[3] = shft[8]; break; } p1 = (PIX_TYPE *)GetImPtr(im)+nx+1; p2 = (PIX_TYPE *)GetImPtr(i0)+nx+1; pfin = (PIX_TYPE *)GetImPtr(im)+ nx*(GetImNy(im)-1)-1; for (; p1 < pfin; p1++, p2++){ ero = *(p1 + *shft_1); dil = *(p1 + *shft_0); for (k = 1; k < na1; k++){ val = *(p1 + shft_1[k]); if (ero > val) ero = val; } for (k = 1; k < na0; k++){ val = *(p1 + shft_0[k]); if (dil < val) dil = val; } if (dil < *p1 && ero == *p1){ *p2 = dil; idpt = FALSE; } else *p2 = *p1; } p1 = (PIX_TYPE *)GetImPtr(im); p2 = (PIX_TYPE *)GetImPtr(i0); MYSWAP(p1, p2, ptmp); } } while (idpt == FALSE); free_image(i0); return(NO_ERROR); } #include "uc_undef.h" #include "us_def.h" ERROR_TYPE us_skeleton(IMAGE *im) { IMAGE *i0; long int shft[9], shft_0[9], shft_1[9], k; PIX_TYPE *p1, *p2, *ptmp, ero, dil; PIX_TYPE *pfin, val; int n, idpt; int na0=0, na1=0; int nx=GetImNx(im); i0 = create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (i0==NULL) return(ERROR); shft[0]= -nx-1; shft[1]=shft[0]+1; shft[2]=shft[1]+1; shft[3]= -1; shft[4] = 0; shft[5]=1; shft[6]= nx-1; shft[7]=shft[6]+1; shft[8]=shft[7]+1; shft_0[2]=0; /* avoid message 'may be used uninitialized in this function' */ /* here we go */ do{ idpt = TRUE; for (n = 0; n < 8; n++){ switch(n) { /* case 0 to 7 ==> homotopic thinning */ case 0 : na1 = 4; na0 = 3; shft_0[0] = shft[0]; shft_0[1] = shft[1]; /* 0 0 0 */ shft_0[2] = shft[2]; /* . 1 . */ shft_1[0] = shft[4]; shft_1[1] = shft[6]; /* 1 1 1 */ shft_1[2] = shft[7]; shft_1[3] = shft[8]; break; case 1 : na1 = 4; na0 = 3; shft_0[0] = shft[2]; shft_0[1] = shft[5]; shft_0[2] = shft[8]; shft_1[0] = shft[0]; shft_1[1] = shft[3]; shft_1[2] = shft[4]; shft_1[3] = shft[6]; break; case 2 : na1 = 4; na0 = 3; shft_0[0] = shft[6]; shft_0[1] = shft[7]; shft_0[2] = shft[8]; shft_1[0] = shft[0]; shft_1[1] = shft[1]; shft_1[2] = shft[2]; shft_1[3] = shft[4]; break; case 3 : na1 = 4; na0 = 3; shft_0[0] = shft[0]; shft_0[1] = shft[3]; shft_0[2] = shft[6]; shft_1[0] = shft[2]; shft_1[1] = shft[4]; shft_1[2] = shft[5]; shft_1[3] = shft[8]; break; case 4 : na1 = 4; na0 = 2; shft_0[0] = shft[1]; shft_0[1] = shft[5]; /* . 0 . */ shft_1[0] = shft[3]; shft_1[1] = shft[4]; /* 1 1 0 */ shft_1[2] = shft[6]; shft_1[3] = shft[7]; /* 1 1 . */ break; case 5 : na1 = 4; na0 = 2; shft_0[0] = shft[5]; shft_0[1] = shft[7]; shft_1[0] = shft[0]; shft_1[1] = shft[1]; shft_1[2] = shft[3]; shft_1[3] = shft[4]; break; case 6 : na1 = 4; na0 = 2; shft_0[0] = shft[3]; shft_0[1] = shft[7]; shft_1[0] = shft[1]; shft_1[1] = shft[2]; shft_1[2] = shft[4]; shft_1[3] = shft[5]; break; case 7 : na1 = 4; na0 = 2; shft_0[0] = shft[1]; shft_0[1] = shft[3]; shft_1[0] = shft[4]; shft_1[1] = shft[5]; shft_1[2] = shft[7]; shft_1[3] = shft[8]; break; } p1 = (PIX_TYPE *)GetImPtr(im)+nx+1; p2 = (PIX_TYPE *)GetImPtr(i0)+nx+1; pfin = (PIX_TYPE *)GetImPtr(im)+ nx*(GetImNy(im)-1)-1; for (; p1 < pfin; p1++, p2++){ ero = *(p1 + *shft_1); dil = *(p1 + *shft_0); for (k = 1; k < na1; k++){ val = *(p1 + shft_1[k]); if (ero > val) ero = val; } for (k = 1; k < na0; k++){ val = *(p1 + shft_0[k]); if (dil < val) dil = val; } if (dil < *p1 && ero == *p1){ *p2 = dil; idpt = FALSE; } else *p2 = *p1; } p1 = (PIX_TYPE *)GetImPtr(im); p2 = (PIX_TYPE *)GetImPtr(i0); MYSWAP(p1, p2, ptmp); } } while (idpt == FALSE); free_image(i0); return(NO_ERROR); } #include "us_undef.h" ERROR_TYPE skeleton(IMAGE *im) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_skeleton(im)); break; case t_USHORT: return(us_skeleton(im)); break; default: (void)sprintf(buf, "Error in skeleton(): \ invalid ImDataType\n"); errputstr(buf); return(ERROR); } return(ERROR); } #include "uc_def.h" /* ** Prune a binary input buffer *until idempotence* has been reached. ** A sequential algorithm is used. Each time a barbule is encountered, ** it is recursively pruned. Values calculated are updated immediately. ** All the processing is done in one scan and within 4-connected graph. */ int uc_bprune(IMAGE *im, int occa, int graph) /* quick and dirty from grilisp */ { /* ** im : I/O image (branches must have a value > 1) ** occa : prune occa times ** graph : 4 ==> 4-connected graph. ** 8 ==> 8-connected graph. */ PIX_TYPE *pim = (PIX_TYPE *)GetImPtr(im); PIX_TYPE *plast = pim+GetImNPix(im)-GetImNx(im)-1; PIX_TYPE *ptr, *p; int count; int nx = GetImNx(im); int nxm1 = nx - 1; int nxp1 = nx + 1; /* Set borders to 0 */ /* cadre(buf_n, 0L); */ /* Here we go! */ switch (graph) { case 4: for (ptr = pim + nx + 1; ptr < plast; ++ptr) { if (*ptr>1) { p = ptr; for (count=0; count1) { p = ptr; for (count=0; count. ***********************************************************************/ #include #include #include "miallib.h" #include "fifo.h" #include "pqueue.h" #if (defined(XLISP)) extern void gc(); #endif /** \addtogroup group_seg * @{ */ #ifndef NO_generic_IMAGE #include "g_def.h" #define SEED 0x01 /* initial value of a seed */ #define NOSEED 0x00 #define BORDER 0xff #define IN_NHQ 0xfe #define IN_PQ 0xfd ERROR_TYPE generic_srg(IMAGE *im1, IMAGE *im2, IMAGE *imse, int ox, int oy, int oz) { /* ** authors: Pierre Soille (1st: 2002) ** IMAGE *im1: grey level image ** IMAGE *im2: image of seeds (UCHAR) ** IMAGE *imse: image for defining the connectivity (UCHAR) ** int ox: origin of SE in x ** int oy: origin of SE in y ** int oz: origin of SE in z ** comment: a variant of seeded region growing as presented in \cite{mehnert-jackway97} */ long int k, *shft, offset, delta, deltacrt, hprior; PIX_TYPE *p1, *p1o, val=PIX_MIN; UCHAR *p2, *p2last, *p2crt, *p2k, *p2o; FIFO4 *nhq, *hq; struct pqueue *pq; long int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; p1 = (PIX_TYPE *)GetImPtr(im1); n = objectpix(imse); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im1), GetImNy(im1), shft); nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); nhq = create_fifo4((nx*ny)/100L); /* neighbouring queue */ if (nhq == NULL){ free((char*)shft); return ERROR; } hq = create_fifo4((nx*ny)/100L); /* holding queue */ if (hq == NULL){ free_fifo4(nhq); free((char*)shft); return ERROR; } pq = (struct pqueue *)pqinit(NULL, nx+ny); /* priority queue */ if (pq == NULL) return ERROR; /* initialise the neighbouring queue NHQ (with their offset to origin) */ if (uc_framebox(im2,box,BORDER)==ERROR){ free((char*)shft); return ERROR; } p2 = (UCHAR *)GetImPtr(im2); p2last = p2 + nx * ny * nz; for (p2crt=p2; p2crt < p2last; p2crt++){ if (*p2crt == NOSEED){ /* usually, there will be less NOSEED then SEED pixels */ for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if (*p2k == SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p1o = p1+offset; p2o = p2+offset; delta=PIX_RANGE; for (k=0; k < n; k++){ if (*(p2o+shft[k])==SEED){ if ( ( deltacrt = abs(*(p1o+shft[k])- *p1o) ) < delta){ delta=deltacrt; val = *(p1o+shft[k]); } } } pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = delta; pqd->val = val; pqd->offset= offset; pqmininsert(pq, pqd); *p2o = IN_PQ; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; /* printf("hprior=%d\n", hprior); */ pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ *(p1+(apqd[0]->offset))=(*apqd)->val; *(p2+(apqd[0]->offset))=SEED; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while ( pqpeek(pq, apqd) != NULL ) { if ((*apqd)->prio != hprior) break; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ *(p1+(apqd[0]->offset))=apqd[0]->val; *(p2+(apqd[0]->offset))=SEED; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ( (offset = (long int)fifo4_remove(hq)) ){ p2crt = p2+offset; for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if ( (*p2k == NOSEED) || (*p2k == IN_PQ) ){ fifo4_add(nhq, (long int)(p2k-p2) ); *p2k=IN_NHQ; } } } } free((char*)shft); free_fifo4(nhq); free_fifo4(hq); free_pq(pq); return NO_ERROR; } #include "g_undef.h" #undef SEED #undef NOSEED #undef BORDER #undef IN_NHQ #undef IN_PQ #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" #define SEED 0x01 /* initial value of a seed */ #define NOSEED 0x00 #define BORDER 0xff #define IN_NHQ 0xfe #define IN_PQ 0xfd ERROR_TYPE us_srg(IMAGE *im1, IMAGE *im2, IMAGE *imse, int ox, int oy, int oz) { /* ** authors: Pierre Soille (1st: 2002) ** IMAGE *im1: grey level image ** IMAGE *im2: image of seeds (UCHAR) ** IMAGE *imse: image for defining the connectivity (UCHAR) ** int ox: origin of SE in x ** int oy: origin of SE in y ** int oz: origin of SE in z ** comment: a variant of seeded region growing as presented in \cite{mehnert-jackway97} */ long int k, *shft, offset, delta, deltacrt, hprior; PIX_TYPE *p1, *p1o, val=PIX_MIN; UCHAR *p2, *p2last, *p2crt, *p2k, *p2o; FIFO4 *nhq, *hq; struct pqueue *pq; long int n, nx, ny, nz; int box[BOXELEM]; PQDATUM apqd[1]; struct node *pqd; p1 = (PIX_TYPE *)GetImPtr(im1); n = objectpix(imse); if (n==ERROR) return ERROR; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return ERROR; /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((UCHAR *)GetImPtr(imse), box, GetImNx(im1), GetImNy(im1), shft); nx = GetImNx(im1); ny = GetImNy(im1); nz = GetImNz(im1); nhq = create_fifo4((nx*ny)/100L); /* neighbouring queue */ if (nhq == NULL){ free((char*)shft); return ERROR; } hq = create_fifo4((nx*ny)/100L); /* holding queue */ if (hq == NULL){ free_fifo4(nhq); free((char*)shft); return ERROR; } pq = (struct pqueue *)pqinit(NULL, nx+ny); /* priority queue */ if (pq == NULL) return ERROR; /* initialise the neighbouring queue NHQ (with their offset to origin) */ if (uc_framebox(im2,box,BORDER)==ERROR){ free((char*)shft); return ERROR; } p2 = (UCHAR *)GetImPtr(im2); p2last = p2 + nx * ny * nz; for (p2crt=p2; p2crt < p2last; p2crt++){ if (*p2crt == NOSEED){ /* usually, there will be less NOSEED then SEED pixels */ for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if (*p2k == SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p1o = p1+offset; p2o = p2+offset; delta=PIX_RANGE; for (k=0; k < n; k++){ if (*(p2o+shft[k])==SEED){ if ( ( deltacrt = abs(*(p1o+shft[k])- *p1o) ) < delta){ delta=deltacrt; val = *(p1o+shft[k]); } } } pqd = (PQDATUM )malloc(sizeof(struct node)); pqd->prio = delta; pqd->val = val; pqd->offset= offset; pqmininsert(pq, pqd); *p2o = IN_PQ; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; /* printf("hprior=%d\n", hprior); */ pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ *(p1+(apqd[0]->offset))=(*apqd)->val; *(p2+(apqd[0]->offset))=SEED; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while ( pqpeek(pq, apqd) != NULL ) { if ((*apqd)->prio != hprior) break; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ *(p1+(apqd[0]->offset))=apqd[0]->val; *(p2+(apqd[0]->offset))=SEED; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ( (offset = (long int)fifo4_remove(hq)) ){ p2crt = p2+offset; for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if ( (*p2k == NOSEED) || (*p2k == IN_PQ) ){ fifo4_add(nhq, (long int)(p2k-p2) ); *p2k=IN_NHQ; } } } } free((char*)shft); free_fifo4(nhq); free_fifo4(hq); free_pq(pq); return NO_ERROR; } #include "us_undef.h" #undef SEED #undef NOSEED #undef BORDER #undef IN_NHQ #undef IN_PQ ERROR_TYPE srg(IMAGE *im1, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { if ( GetImDataType(im2) != t_UCHAR ){ (void)sprintf(buf,"srg(): image of seeds must be of type UCHAR\n"); errputstr(buf); return(ERROR); } if ( GetImDataType(im3) != t_UCHAR ){ (void)sprintf(buf,"srg(): image of for neighbourhood must be of type UCHAR\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(im1)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_srg(im1,im2,im3,ox,oy,oz)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_srg(im1,im2,im3,ox,oy,oz)); break; #endif case t_USHORT: return(us_srg(im1,im2,im3,ox,oy,oz)); break; default: (void)sprintf(buf,"srg(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" #define SEED 0x04 /* seeds have a class label larger than this value */ #define NOSEED 0x00 #define BORDER 0x01 #define IN_NHQ 0x02 #define IN_PQ 0x03 #define DELTA_MAX UINT32_MAX #define SEEDS_TYPE UINT32 /* !!! type dependent call to framebox */ #define SEEDS_TYPE_MIN UINT32_MIN /* !!! type dependent call to framebox */ ERROR_TYPE generic_mssrg(IMAGE **imap, int nc, IMAGE *im2, IMAGE *imse, int ox, int oy, int oz) { /* ** authors: ** IMAGE *imap: array of grey level images ** int nc: number of channels ** IMAGE *im2: image of seeds with class labels ** IMAGE *imse: image for defining the connectivity (SE) ** int ox: origin of SE in x ** int oy: origin of SE in y ** int oz: origin of SE in z ** comment: */ long int k, *shft, offset, delta, deltacrt, hprior; PIX_TYPE **pim; SEEDS_TYPE *p2, *p2last, *p2crt, *p2k, *p2o, val=SEEDS_TYPE_MIN; FIFO4 *nhq, *hq; struct pqueue *pq; long int n, nx, ny, nz; int box[BOXELEM]; long int i, db, b, ofsk; PQDATUM apqd[1]; struct node *pqd; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); for (i=0; i= SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p2o = p2+offset; delta=DELTA_MAX; for (k=0; k < n; k++){ ofsk=offset+shft[k]; if (*(p2o+shft[k])>=SEED){ deltacrt=0; for (b=0; bprio = delta; pqd->val = val; pqd->offset= offset; pqmininsert(pq, pqd); *p2o = IN_PQ; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ /* *(p1+(apqd[0]->offset))=(*apqd)->val; */ *(p2+(apqd[0]->offset))=(*apqd)->val; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while ( pqpeek(pq, apqd) != NULL ) { if ((*apqd)->prio != hprior) break; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ /* *(p1+(apqd[0]->offset))=apqd[0]->val; */ *(p2+(apqd[0]->offset))=(*apqd)->val; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ( (offset = (long int)fifo4_remove(hq)) ){ p2crt = p2+offset; for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if ( (*p2k == NOSEED) || (*p2k == IN_PQ) ){ fifo4_add(nhq, (long int)(p2k-p2) ); *p2k=IN_NHQ; } } } } free(pim); free((char*)shft); free_fifo4(nhq); free_fifo4(hq); free_pq(pq); return NO_ERROR; } #include "g_undef.h" #undef SEED #undef NOSEED #undef BORDER #undef IN_NHQ #undef IN_PQ #undef DELTA_MAX #undef SEEDS_TYPE #undef SEEDS_TYPE_MIN #endif /* #ifndef NO_generic_IMAGE */ #ifndef NO_generic_IMAGE #include "us_def.h" #define SEED 0x04 /* seeds have a class label larger than this value */ #define NOSEED 0x00 #define BORDER 0x01 #define IN_NHQ 0x02 #define IN_PQ 0x03 #define DELTA_MAX UINT32_MAX #define SEEDS_TYPE UINT32 /* !!! type dependent call to framebox */ #define SEEDS_TYPE_MIN UINT32_MIN /* !!! type dependent call to framebox */ ERROR_TYPE us_mssrg(IMAGE **imap, int nc, IMAGE *im2, IMAGE *imse, int ox, int oy, int oz) { /* ** authors: ** IMAGE *imap: array of grey level images ** int nc: number of channels ** IMAGE *im2: image of seeds with class labels ** IMAGE *imse: image for defining the connectivity (SE) ** int ox: origin of SE in x ** int oy: origin of SE in y ** int oz: origin of SE in z ** comment: */ long int k, *shft, offset, delta, deltacrt, hprior; PIX_TYPE **pim; SEEDS_TYPE *p2, *p2last, *p2crt, *p2k, *p2o, val=SEEDS_TYPE_MIN; FIFO4 *nhq, *hq; struct pqueue *pq; long int n, nx, ny, nz; int box[BOXELEM]; long int i, db, b, ofsk; PQDATUM apqd[1]; struct node *pqd; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); for (i=0; i= SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p2o = p2+offset; delta=DELTA_MAX; for (k=0; k < n; k++){ ofsk=offset+shft[k]; if (*(p2o+shft[k])>=SEED){ deltacrt=0; for (b=0; bprio = delta; pqd->val = val; pqd->offset= offset; pqmininsert(pq, pqd); *p2o = IN_PQ; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ /* *(p1+(apqd[0]->offset))=(*apqd)->val; */ *(p2+(apqd[0]->offset))=(*apqd)->val; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); while ( pqpeek(pq, apqd) != NULL ) { if ((*apqd)->prio != hprior) break; pqminremove(pq, apqd); if ( *(p2+(apqd[0]->offset)) == IN_PQ){ /* *(p1+(apqd[0]->offset))=apqd[0]->val; */ *(p2+(apqd[0]->offset))=(*apqd)->val; fifo4_add(hq, apqd[0]->offset); } free((char*) *apqd); } } while ( (offset = (long int)fifo4_remove(hq)) ){ p2crt = p2+offset; for (k=0; k < n; k++){ p2k = p2crt + shft[k]; if ( (*p2k == NOSEED) || (*p2k == IN_PQ) ){ fifo4_add(nhq, (long int)(p2k-p2) ); *p2k=IN_NHQ; } } } } free(pim); free((char*)shft); free_fifo4(nhq); free_fifo4(hq); free_pq(pq); return NO_ERROR; } #include "us_undef.h" #undef SEED #undef NOSEED #undef BORDER #undef IN_NHQ #undef IN_PQ #undef DELTA_MAX #undef SEEDS_TYPE #undef SEEDS_TYPE_MIN #endif /* #ifndef NO_generic_IMAGE */ /* multispectral seeded region growing */ ERROR_TYPE mssrg(IMAGE **imap, int nc, IMAGE *im2, IMAGE *im3, int ox, int oy, int oz) { if ( GetImDataType(im2) != t_UINT32 ){ (void)sprintf(buf,"mssrg(): image of seeds must be of type UINT32\n"); errputstr(buf); return(ERROR); } switch (GetImDataType(imap[0])){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_mssrg(imap,nc,im2,im3,ox,oy,oz)); break; #endif case t_USHORT: return(us_mssrg(imap,nc,im2,im3,ox,oy,oz)); break; default: (void)sprintf(buf,"mssrg(): invalid pixel type\n"); errputstr(buf); return(ERROR); } return(NO_ERROR); } #ifndef NO_generic_IMAGE #include "g_def.h" #define SEED 0x04 /* seeds have a class label larger than this value */ #define NOSEED 0x00 #define BORDER 0x01 #define IN_NHQ 0x02 #define IN_PQ 0x03 #define DELTA_MAX UINT32_MAX /* type dependent */ #define SEEDS_TYPE UINT32 /* !!! type dependent call to framebox */ #define SEEDS_TYPE_MIN UINT32_MIN /* !!! type dependent call to framebox */ ERROR_TYPE generic_mssrgcore(IMAGE **imap, int nc, IMAGE *im2, IMAGE *imse, int ox, int oy, int oz) { /* ** authors: ** IMAGE *imap: array of grey level grey level images ** int nc: number of channels ** IMAGE *im2: image of seeds with class labels ** IMAGE *imse: image for defining the connectivity (SE) ** int ox: origin of SE in x ** int oy: origin of SE in y ** int oz: origin of SE in z ** comment: */ long int k, *shft, offset, sof=0, count1=0, count2=0, delta, deltacrt, hprior; PIX_TYPE **pim; SEEDS_TYPE *p2, *p2last, *p2crt, *p2k, *p2o, val=SEEDS_TYPE_MIN; FIFO4 *nhq, *hq; struct pqueue *pq; long int n, nx, ny, nz; int box[BOXELEM]; long int i, db, b, ofsk; PQDATUM apqd[1]; struct node *pqd; pim = (PIX_TYPE **)calloc(nc, sizeof(PIX_TYPE **)); for (i=0; i= SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p2o = p2+offset; delta=DELTA_MAX; count1++; for (k=0; k < n; k++){ ofsk=offset+shft[k]; if (*(p2o+shft[k])>=SEED){ deltacrt=0; for (b=0; bprio = delta; pqd->val = val; pqd->offset= offset; pqd->sof = sof; pqmininsert(pq, pqd); *p2o = IN_PQ; } else count1=count1; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqminremove(pq, apqd); offset = apqd[0]->offset; if ( *(p2+offset) == IN_PQ){ /* *(p1+(apqd[0]->offset))=(*apqd)->val; */ *(p2+offset)=(*apqd)->val; sof=apqd[0]->sof; for (b=0; bprio != hprior) break; pqminremove(pq, apqd); offset = apqd[0]->offset; if ( *(p2+offset) == IN_PQ){ /* *(p1+(apqd[0]->offset))=apqd[0]->val; */ *(p2+offset)=(*apqd)->val; sof=apqd[0]->sof; #if DEBUG if (sof>nx*ny) printf("sof=%ld, count1=%ld, count2=%ld\n", sof, count1, count2); #endif for (b=0; b= SEED){ fifo4_add(nhq, (long int)(p2crt-p2) ); *p2crt=IN_NHQ; break; } } } } /* here we go */ while ( (fifo4_empty(nhq)==0) || (pqpeek(pq, apqd) != NULL) ){ while ( (offset = (long int)fifo4_remove(nhq)) ){ p2o = p2+offset; delta=DELTA_MAX; count1++; for (k=0; k < n; k++){ ofsk=offset+shft[k]; if (*(p2o+shft[k])>=SEED){ deltacrt=0; for (b=0; bprio = delta; pqd->val = val; pqd->offset= offset; pqd->sof = sof; pqmininsert(pq, pqd); *p2o = IN_PQ; } else count1=count1; } if (pqpeek(pq, apqd) != NULL){ hprior = (*apqd)->prio; pqminremove(pq, apqd); offset = apqd[0]->offset; if ( *(p2+offset) == IN_PQ){ /* *(p1+(apqd[0]->offset))=(*apqd)->val; */ *(p2+offset)=(*apqd)->val; sof=apqd[0]->sof; for (b=0; bprio != hprior) break; pqminremove(pq, apqd); offset = apqd[0]->offset; if ( *(p2+offset) == IN_PQ){ /* *(p1+(apqd[0]->offset))=apqd[0]->val; */ *(p2+offset)=(*apqd)->val; sof=apqd[0]->sof; #if DEBUG if (sof>nx*ny) printf("sof=%ld, count1=%ld, count2=%ld\n", sof, count1, count2); #endif for (b=0; b. ***********************************************************************/ /** @file * See also \cite soille2005ivc * @author Pierre Soille */ #include #include #include "miallib.h" /** \addtogroup group_hmtsk * @{ */ #include "uc_def.h" void uc_switchop(PIX_TYPE *im1, PIX_TYPE *im2, long int nx, long int ny, long int nz, int *box, long int *shft, long int n) { PIX_TYPE *p1, *p2, minval, maxval; long int k, x, y, z; long int lstx, lsty, lstz; lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; for (z = box[4]; z < lstz; z++){ p1 = im1 + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = im2 + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ /* compute min & max in SE */ minval = *(p1 + shft[0]); maxval = *(p1 + shft[0]); for (k = 1; k < n; k++){ if (minval > *(p1 + shft[k])) minval = *(p1 + shft[k]); else if (maxval < *(p1 + shft[k])) maxval = *(p1 + shft[k]); } /* test whether to thin or thick or id */ if (*p1 < minval) /* then thick */ *p2=minval; else if (*p1 > maxval) /* then thin */ *p2=maxval; else /* leave as it is */ *p2=*p1; p1++; p2++; } p1 += box[0] + box[1]; p2 += box[0] + box[1]; } } } #include "uc_undef.h" /** * Switch operator \cite soille2005ivc * * @param im : input image * @param imse : image coding structuring element * @param ox : integer for x-coordinate origin of composite structuring element * @param oy : integer for x-coordinate origin of composite structuring element * @param oz : integer for x-coordinate origin of composite structuring element * * @return new image holding the switch transformed input image using the specified composite structuring element */ IMAGE *switchop(IMAGE *im, IMAGE *imse, int ox, int oy, int oz) { IMAGE *imout; int box[BOXELEM]; int n; long int *shft; /* create shift array */ n = objectpix(imse); if (n==ERROR) /* no point in SE */ return NULL; shft = (long int *)calloc(n, sizeof(long int)); if (shft == NULL) return NULL; /* create output image */ imout = (IMAGE *)create_image(GetImDataType(im), GetImNx(im), GetImNy(im), GetImNz(im)); if (imout == NULL){ (void)sprintf(buf,"erode(): not enough memory!\n"); errputstr(buf); return(imout); } /* Take SE into account */ box[0] = GetImNx(imse); box[1] = GetImNy(imse); box[2] = GetImNz(imse); box[3] = ox; box[4] = oy; box[5] = oz; set_shift_and_box((unsigned char *)GetImPtr(imse), box, GetImNx(im), GetImNy(im), shft); switch (GetImDataType(im)){ case t_UCHAR: uc_switchop((UCHAR *)GetImPtr(im), (UCHAR *)GetImPtr(imout), GetImNx(im), GetImNy(im), GetImNz(im), box, shft, n); break; default: (void)sprintf(buf,"switchop(): invalid pixel type\n"); errputstr(buf); free_image(imout); imout=NULL; } free((char *) shft); return(imout); } /*@}*/ jeolib-miallib-1.1.6/core/c/transition.c000066400000000000000000000112331467232417700201170ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include #include "miallib.h" #include "uc_def.h" IMAGE *uc_transgradfirst(IMAGE *im1, int graph) { IMAGE *im2; PIX_TYPE *p1, *p2, crtval; long int nx, ny, nz; long int x, y, z; long int lstx, lsty, lstz; long int low=PIX_MIN-1; // GLOUP! for long data types... long int high=PIX_MAX+1; // GLOUP! for long data types... int i; int box[6]; int shft[8]; int n; /* create output image */ im2 = (IMAGE *)create_image(GetImDataType(im1), GetImNx(im1), GetImNy(im1), GetImNz(im1)); if (im2 == NULL){ (void)sprintf(buf,"transgrad(): not enough memory!\n"); errputstr(buf); return(im2); } n=graph; nx=GetImNx(im1); ny=GetImNy(im1); nz=GetImNz(im1); shft[0]= -nx-1; shft[1]=-nx; shft[2]=-nx+1; shft[3]= -1; shft[4]=1; shft[5]= nx-1; shft[6]=nx; shft[7]=nx+1; if (GetImNy(im1) == 1) {BOX_1D;} else if (GetImNz(im1) == 1) {BOX_2D;} else {BOX_3D;} lstx = nx - box[1]; lsty = ny - box[3]; lstz = nz - box[5]; for (z = box[4]; z < lstz; z++){ p1 = (PIX_TYPE *)GetImPtr(im1) + nx * ny * z; p1 += nx * box[2]; p1 += box[0]; p2 = (PIX_TYPE *)GetImPtr(im2) + nx * ny * z; p2 += nx * box[2]; p2 += box[0]; for (y = box[2]; y < lsty; y++){ for (x = box[0]; x < lstx; ++x){ low=PIX_MIN-1; high=PIX_MAX+1; for (i=0; ilow) low=crtval; } else if ( (crtval>*p1) && (crtval= *p1-alpha) && (crtval>low) ){ low=crtval; } // else if (crtval==*p1+alpha) else if ( (crtval>*p1) && (crtval<= *p1+alpha) && (crtval. ***********************************************************************/ /* macro definitions for unsigned long int data types */ #define FLOATING 0 #define SIGNED 0 #define SUM_TYPE unsigned long int #define OVFL_TEST 0 #define t_PIX_TYPE t_UINT32 #define PIX_TYPE UINT32 #define PIX_MIN UINT32_MIN #define PIX_MAX UINT32_MAX #define PIX_MSB 0x80000000 #define PIX_RANGE PIX_MAX #define BitPerPixel 32 jeolib-miallib-1.1.6/core/c/u32_undef.h000066400000000000000000000021171467232417700175250ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef SUM_TYPE #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MSB #undef PIX_RANGE #undef BitPerPixel jeolib-miallib-1.1.6/core/c/u64_def.h000066400000000000000000000022341467232417700171670ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for unsigned long int data types */ #define FLOATING 0 #define SIGNED 0 #define SUM_TYPE unsigned long int #define OVFL_TEST 0 #define t_PIX_TYPE t_UINT64 #define PIX_TYPE UINT64 #define PIX_MIN UINT64_MIN #define PIX_MAX UINT64_MAX #define PIX_MSB 0x8000000000000000 #define BitPerPixel 64 jeolib-miallib-1.1.6/core/c/u64_undef.h000066400000000000000000000020751467232417700175350ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro undefinitions for unsigned long int data types */ #undef FLOATING #undef SIGNED #undef SUM_TYPE #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MSB #undef BitPerPixel jeolib-miallib-1.1.6/core/c/uc_def.h000066400000000000000000000022431467232417700171600ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for unsigned char data types */ #define FLOATING 0 #define SIGNED 0 #define OVFL_TEST 1 #define t_PIX_TYPE t_UCHAR #define PIX_TYPE UCHAR #define PIX_MIN UCHAR_MIN #define PIX_MAX UCHAR_MAX #define PIX_RANGE 0xff #define PIX_MAXP1 (UCHAR_MAX+1) #define PIX_MSB 0x80 #define BitPerPixel 8 jeolib-miallib-1.1.6/core/c/uc_undef.h000066400000000000000000000021071467232417700175220ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* undefine unsigned char data type definitions */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_RANGE #undef PIX_MAXP1 #undef PIX_MSB #undef BitPerPixel jeolib-miallib-1.1.6/core/c/us_def.h000066400000000000000000000022561467232417700172040ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* macro definitions for unsigned short char data types */ #define FLOATING 0 #define SIGNED 0 #define OVFL_TEST 1 #define t_PIX_TYPE t_USHORT #define PIX_TYPE USHORT #define PIX_MIN USHORT_MIN #define PIX_MAX USHORT_MAX #define PIX_MAXP1 (USHORT_MAX+1) #define PIX_MSB 0x8000 #define PIX_RANGE PIX_MAX #define BitPerPixel 16 jeolib-miallib-1.1.6/core/c/us_undef.h000066400000000000000000000021071467232417700175420ustar00rootroot00000000000000/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /* undefine unsigned char data type definitions */ #undef FLOATING #undef SIGNED #undef OVFL_TEST #undef t_PIX_TYPE #undef PIX_TYPE #undef PIX_MIN #undef PIX_MAX #undef PIX_MAXP1 #undef PIX_MSB #undef PIX_RANGE #undef BitPerPixel jeolib-miallib-1.1.6/core/c/uswilk.c000066400000000000000000001753161467232417700172600ustar00rootroot00000000000000/*********************************************************************** Author(s): Michael Wilkinson, Arnold Meijster, and Jos Roerdink Copyright (C) 2000 Michael Wilkinson, Arnold Meijster, and Jos Roerdink Adapted by Pierre Soille to fit miallib with permission of the authors Copyright (C) 2000-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /** * @file uswilk.c * * @author (c) Michael Wilkinson, Arnold Meijster, and Jos Roerdink 18-09-2000 * @date * * @details Based on max-tree algorithm described in \cite wilkinson-roerdink2000 see also \cite meijster-wilkinson2002. Adapted by Pierre Soille on 20/21-09-2000 to fit miallib (see macro functions AddToNeighbour() and Link()). * * */ /* This program computes the grey scale attribute opening. * The input is a grey scale image (im), and its output is * a grey-scale image, which is stored in an array (parent), * which is also used to store the trees needed for Tarjan's * algorithm. * The time complexity of this algorithm is linear in the * number of pixels. * * (c) Michael Wilkinson, Arnold Meijster,and Jos Roerdink 18-09-2000 * */ #include #include #include "miallib.h" #ifdef DMALLOC #include #endif #if (defined(XLISP)) extern void gc(); #endif /** @defgroup group_opclo Opening and closing * Functions dealing with morphological opening and closing. * @{ */ #define MAXGREYVAL 65536 #define FALSE 0 #define TRUE 1 #define ACTIVE_ROOT -1 #define DONE_ROOT -2 typedef int greyval; /* used for index to sorted image */ typedef unsigned short byte; typedef void ***AuxDataType; /* 2D array of void pointers for auxiliary data */ typedef greyval **Image; /* Guess */ typedef byte **ByteImage; /* Guess again */ int *SortPixelsext; /* array storing the sorted pixels */ Image imext; /* input image */ Image parentext; /* output image doubling as storage for Tarjan's trees */ AuxDataType auxdataext; /* Auxiliary data for attributes */ /* The type Neighbours2D stores the number of neighbours of a pixel and the offsets to neighbours in two arrays. The (first) two indexes of the arrays are given by (x==0) + ((x == width -1) << 1) and (y==0) + ((y == height -1) << 1). Thus all non boundary pixels yield index [0][0], all non-corner, boundary pixels [0][1], [1][0], [0][2], and [2][0]. The corner pixels have indices [1][1], [2][2], [1][2], and [2][1]. */ typedef struct { long number[3][3], /* number of neighbours */ offsets[3][3][8]; /* offsets to neighbours */ } Neighbours2D; void Init_4_Neighbours2D ( Neighbours2D *neighbours, int width) /* initializes Neighbour2D type for four connectedness */ { neighbours->number[0][0] = 4; neighbours->offsets[0][0][0] = -1; neighbours->offsets[0][0][1] = +1; neighbours->offsets[0][0][2] = -width; neighbours->offsets[0][0][3] = +width; neighbours->number[1][0] = 3; neighbours->offsets[1][0][0] = +1; neighbours->offsets[1][0][1] = -width; neighbours->offsets[1][0][2] = +width; neighbours->number[2][0] = 3; neighbours->offsets[2][0][0] = -1; neighbours->offsets[2][0][1] = -width; neighbours->offsets[2][0][2] = +width; neighbours->number[0][1] = 3; neighbours->offsets[0][1][0] = -1; neighbours->offsets[0][1][1] = +1; neighbours->offsets[0][1][2] = +width; neighbours->number[0][2] = 3; neighbours->offsets[0][2][0] = -1; neighbours->offsets[0][2][1] = +1; neighbours->offsets[0][2][2] = -width; neighbours->number[1][1] = 2; neighbours->offsets[1][1][0] = +1; neighbours->offsets[1][1][1] = +width; neighbours->number[2][1] = 2; neighbours->offsets[2][1][0] = -1; neighbours->offsets[2][1][1] = +width; neighbours->number[1][2] = 2; neighbours->offsets[1][2][0] = +1; neighbours->offsets[1][2][1] = -width; neighbours->number[2][2] = 2; neighbours->offsets[2][2][0] = -1; neighbours->offsets[2][2][1] = -width; } void Init_8_Neighbours2D ( Neighbours2D *neighbours, int width) /* initializes Neighbour2D type for eight connectedness */ { neighbours->number[0][0] = 8; neighbours->offsets[0][0][0] = -1; neighbours->offsets[0][0][1] = +1; neighbours->offsets[0][0][2] = -width; neighbours->offsets[0][0][3] = +width; neighbours->offsets[0][0][4] = -width-1; neighbours->offsets[0][0][5] = +width+1; neighbours->offsets[0][0][6] = -width+1; neighbours->offsets[0][0][7] = +width-1; neighbours->number[1][0] = 5; neighbours->offsets[1][0][0] = +1; neighbours->offsets[1][0][1] = -width; neighbours->offsets[1][0][2] = +width; neighbours->offsets[1][0][3] = -width+1; neighbours->offsets[1][0][4] = +width+1; neighbours->number[2][0] = 5; neighbours->offsets[2][0][0] = -1; neighbours->offsets[2][0][1] = -width; neighbours->offsets[2][0][2] = +width; neighbours->offsets[2][0][3] = -width-1; neighbours->offsets[2][0][4] = +width-1; neighbours->number[0][1] = 5; neighbours->offsets[0][1][0] = -1; neighbours->offsets[0][1][1] = +1; neighbours->offsets[0][1][2] = +width; neighbours->offsets[0][1][3] = +width-1; neighbours->offsets[0][1][4] = +width+1; neighbours->number[0][2] = 5; neighbours->offsets[0][2][0] = -1; neighbours->offsets[0][2][1] = +1; neighbours->offsets[0][2][2] = -width; neighbours->offsets[0][2][3] = -width-1; neighbours->offsets[0][2][4] = -width+1; neighbours->number[1][1] = 3; neighbours->offsets[1][1][0] = +1; neighbours->offsets[1][1][1] = +width; neighbours->offsets[1][1][2] = +width+1; neighbours->number[2][1] = 3; neighbours->offsets[2][1][0] = -1; neighbours->offsets[2][1][1] = +width; neighbours->offsets[2][1][2] = +width-1; neighbours->number[1][2] = 3; neighbours->offsets[1][2][0] = +1; neighbours->offsets[1][2][1] = -width; neighbours->offsets[1][2][2] = -width+1; neighbours->number[2][2] = 3; neighbours->offsets[2][2][0] = -1; neighbours->offsets[2][2][1] = -width-1; neighbours->offsets[2][2][2] = -width-1; } #define NEIGH_INDEX(A,B) (((A)==0) + (( (A)==(B-1))<<1)) /* Returns the correct index within the arrays in the Neighbours2D struct type. A must be the current coordinate, B the corresponding array dimension. */ /********************* IMAGE I/O ********************************** */ AuxDataType CreateAuxData ( int width, int height ) /* initialize auxiliary data array */ { AuxDataType auxdata; void **buf; int i; #if (defined(XLISP)) gc(); #endif auxdata = (AuxDataType)malloc (height*sizeof(void **)); buf = (void **)calloc (width*height, sizeof(void *)); if ((auxdata == NULL) || (buf == NULL)) { fprintf (stderr, "fatal error: Malloc failed in CreateAuxData (height=%d, width=%d)\n", height, width); exit (-1); } auxdata[0] = buf; for (i=1; i=0; i--) { idx[i] = SortPixels+s; s+=hist[i]; } /* Now we do the actual sorting */ for (i=0, tmp=im; i= 0) \ root = parent[root]; \ newroot = root; \ if ( (im[root] == im[pixel]) || \ (parent[root] == ACTIVE_ROOT)) \ { if ( parent[root] == DONE_ROOT ) \ parent[pixel] = DONE_ROOT; \ else \ { auxdata[pixel] = auxdata[root]; \ (*AddToAuxData)( auxdata[pixel],x,y ); \ } \ parent[root] = pixel; \ newroot = pixel; \ } \ else \ parent[pixel] = DONE_ROOT; \ r = (p); \ while (r != root) \ { h=parent[r]; \ parent[r] = newroot; \ r = h; \ } \ } /* The new Link function corrected by MW following comments by PS */ #define Link(p) \ { \ root = (p); /* Find the root of p */\ while ( parent[root] >= 0 ) \ root = parent[root]; \ newroot = root; /* stores the new root */ \ if (root!=pixel){ /* not in same component yet */ \ if ((im[root] == im[pixel]) || /* if same greylevel */\ (parent[root] == ACTIVE_ROOT)) /* or not DONE */\ { /* Merge components */\ if ( parent[root] == DONE_ROOT ) /* if neighbour DONE */\ { if ( parent[pixel] == ACTIVE_ROOT ) /* and pixel isn't */\ { DisposeAuxData(auxdata[pixel]); /* this one is DONE */\ parent[pixel] = DONE_ROOT; \ } \ } \ else \ if (parent[pixel] == DONE_ROOT) /* if pixel is DONE */\ { if (parent[root] == ACTIVE_ROOT) /* so is the neighbour*/\ DisposeAuxData(auxdata[root]); \ } \ else \ { auxdata[pixel] = /* otherwise MERGE DATA*/\ (*MergeAuxData)( auxdata[root], auxdata[pixel] ); \ } \ parent[root] = pixel; /* make link */ \ newroot = pixel; /* update new root */ \ } \ else /* done processing this component */\ if ( parent[pixel] == ACTIVE_ROOT ) \ { DisposeAuxData(auxdata[pixel]); \ parent[pixel] = DONE_ROOT; \ } \ r = (p); \ while (r != root) /* path compression starts here */\ { h=parent[r]; \ parent[r] = newroot; \ r = h; \ } /* end path compression */\ } \ } void GreyAttributeClosing(double lambdaVal, int width, int height, greyval *im, greyval *parent, void **auxdata, void *(*NewAuxData)(int, int), void (*DisposeAuxData)(void *), void (*AddToAuxData)(void *,int, int), void *(*MergeAuxData)(void *, void*), double (*Attribute)(void *), int graph) { /* double lambdaVal, /\* threshold on attribute *\/ */ /* int width, /\* image width *\/ */ /* int height, /\* image height *\/ */ /* greyval *im, /\* input image *\/ */ /* greyval *parent, /\* output image (also stores */ /* Tarjan trees) *\/ */ /* void **auxdata, /\* auxilliary data for */ /* attributes *\/ */ /* /\* last parameters are function pointers for */ /* creating, disposing, adding to, and merging */ /* auxilliary data, and computation of attribute */ /* *\/ */ /* void *(*NewAuxData)(int, int), */ /* void (*DisposeAuxData)(void *), */ /* void (*AddToAuxData)(void *,int, int), */ /* void *(*MergeAuxData)(void *, void*), */ /* double (*Attribute)(void *), */ /* int graph */ int pixel, /* pixel coordinate in form width*y+x */ imsize=width*height, /* image size */ linkmade, /* keeps track of whether current pixel has been linked to any neighbour */ **idx=malloc(MAXGREYVAL * sizeof(int *)), /* list of pointers to sections of the SORTED pixels containing pixels of the same greylevel */ *start, *finish, /* start and finnish of current section */ curneigh, numneighs, /* current neighbour and number of neighbours */ NID_X, NID_Y; /* neighbour list indexes for x and y */ long *neigh_offsets; /* list of offsets to neighbours */ greyval gval; /* current grey level */ Neighbours2D neighbours; /* neighbour list structure */ int x, y, /* current pixel x and y */ h, r, root,newroot, /* auxilliary variables for root finding */ neigh; /* current neighbour */ greyval *current; /* pointer to current pixel */ /* Initialize neighbour list for x-connectivity */ if (graph==8) Init_8_Neighbours2D(&neighbours, width); else Init_4_Neighbours2D(&neighbours, width); /* Sort pixels first */ PixelSortforClosing (imsize, im, SortPixelsext, idx); finish=SortPixelsext; /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (gval=0;gval im[neigh]) || (( neigh im[neigh]) || (( neigh= lambdaVal) ) /* and criterion met */ { parent[pixel] = DONE_ROOT; /* root is DONE_ROOT */ (*DisposeAuxData)( auxdata[pixel] ); /* get rid of auxilliary data */ } } /* Finnished one grey level */ } /* done building trees */ pixel = *(finish-1); if (parent[pixel] == ACTIVE_ROOT ) /* remove any remaining */ { parent[pixel] = DONE_ROOT; /* ACTIVE roots */ (*DisposeAuxData)( auxdata[pixel] ); } /* Forall pixels in reverse processing order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) parent[*current] = (parent[*current] < 0 ? im[*current] : parent[parent[*current]]); free(idx); return; } void GreyAttributeOpening( double lambdaVal, /* threshold on attribute */ int width, /* image width */ int height, /* image height */ greyval *im, /* input image */ greyval *parent, /* output image (also stores Tarjan trees) */ void **auxdata, /* auxilliary data for attributes */ /* last parameters are function pointers for creating, disposing, adding to, and merging auxilliary data, and computation of attribute */ void *(*NewAuxData)(int, int), void (*DisposeAuxData)(void *), void (*AddToAuxData)(void *,int, int), void *(*MergeAuxData)(void *, void*), double (*Attribute)(void *), int graph ) { int pixel, /* pixel coordinate in form width*y+x */ imsize=width*height, /* image size */ linkmade, /* keeps track of whether current pixel has been linked to any neighbour */ **idx=malloc(MAXGREYVAL * sizeof(int *)), /* list of pointers to sections of the SORTED pixels containing pixels of the same greylevel */ *start, *finish, /* start and finnish of current section */ curneigh, numneighs, /* current neighbour and number of neighbours */ NID_X, NID_Y; /* neighbour list indexes for x and y */ long *neigh_offsets; /* list of offsets to neighbours */ greyval gval; /* current grey level */ Neighbours2D neighbours; /* neighbour list structure */ int x, y, /* current pixel x and y */ h, r, root,newroot, /* auxilliary variables for root finding */ neigh; /* current neighbour */ greyval *current; /* pointer to current pixel */ /* Initialize neighbour list for x-connectivity */ if (graph==8) Init_8_Neighbours2D(&neighbours, width); else Init_4_Neighbours2D(&neighbours, width); /* Sort pixels first */ PixelSortforOpening (imsize, im, SortPixelsext, idx); finish=SortPixelsext; /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (gval=MAXGREYVAL-1; gval>=0; gval-- ) { /* process one grey level at a time */ start=finish; /* start is the previous finnish */ finish=idx[gval]; /* look up finnish of current greylevel section */ for (current=start; current= lambdaVal) ) /* and criterion met */ { parent[pixel] = DONE_ROOT; /* root is DONE_ROOT */ (*DisposeAuxData)( auxdata[pixel] ); /* get rid of auxilliary data */ } } /* Finnished one grey level */ } /* done building trees */ pixel = *(finish-1); if (parent[pixel] == ACTIVE_ROOT ) /* remove any remaining */ { parent[pixel] = DONE_ROOT; /* ACTIVE roots */ (*DisposeAuxData)( auxdata[pixel] ); } /* Forall pixels in reverse processing order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) parent[*current] = (parent[*current] < 0 ? im[*current] : parent[parent[*current]]); free(idx); return; } /********************** Attribute functions ***************************/ /**********************************************************************/ /* typedefs and functions for surface area openings and closings */ /**********************************************************************/ typedef struct { int area; } SurfaceData; void *NewSurfaceData( int x, int y ) { SurfaceData *surfacedata = (SurfaceData *) malloc(sizeof(SurfaceData)); surfacedata->area=1; /* fprintf(stderr, "surfacedata in alloc=%d\n", (int) surfacedata); */ return ((void *) surfacedata); } void DisposeSurfaceData( void *surfacedata ) { if (surfacedata!=NULL){ /* fprintf(stderr, "surfacedata in free=%d\n", (int) surfacedata); */ free(surfacedata); surfacedata=NULL; } /* else fprintf(stderr, "NULL surfacedata in free=%d\n", (int) surfacedata); */ } void AddToSurfaceData( void *surfacedata, int x, int y ) { SurfaceData *surfdata = (SurfaceData *) surfacedata; surfdata->area ++; } void *MergeSurfaceData ( void *rootdata, void *pixeldata ) { SurfaceData *rootinert = (SurfaceData *) rootdata, *pixelinert = (SurfaceData *) pixeldata; pixelinert->area += rootinert->area; if(rootdata==NULL) fprintf(stderr, "NULL rootdata in free=%ld !!!!\n", ( long int) rootdata); /* free(rootdata); replaced by following line */ DisposeSurfaceData(rootdata); return pixeldata; } double SurfaceAttribute ( void *pixeldata ) { SurfaceData *surface = pixeldata; return ((double)(surface->area)); } /**********************************************************************/ /* Typedefs and functions for Minimum Enclosed Rectangle attributes */ /**********************************************************************/ typedef struct { int x_min, x_max, y_min, y_max; } EnclRectData; void *NewEnclRectData( int x, int y ) { EnclRectData *rectdata = (EnclRectData *)malloc(sizeof(EnclRectData)); rectdata->x_min=x; rectdata->x_max=x; rectdata->y_min=y; rectdata->y_max=y; return ((void *) rectdata); } void DisposeEnclRectData( void *rectdata ) { if (rectdata!=NULL){ free(rectdata); rectdata=NULL; } } void AddToEnclRectData( void *rectdata, int x, int y ) { EnclRectData *rootdata = (EnclRectData *) rectdata; rootdata->x_min = (rootdata->x_min > x ) ? x : rootdata->x_min; rootdata->x_max = (rootdata->x_max < x ) ? x : rootdata->x_max; rootdata->y_min = (rootdata->y_min > y ) ? y : rootdata->y_min; rootdata->y_max = (rootdata->y_max < y ) ? y : rootdata->y_max; return; } void *MergeEnclRectData( void *rootdata, void *pixeldata ) { EnclRectData *rootrect = (EnclRectData *) rootdata, *pixelrect = (EnclRectData *) pixeldata; pixelrect->x_min = (pixelrect->x_min > rootrect->x_min) ? rootrect->x_min : pixelrect->x_min; pixelrect->x_max = (pixelrect->x_max < rootrect->x_max) ? rootrect->x_max : pixelrect->x_max; pixelrect->y_min = (pixelrect->y_min > rootrect->y_min) ? rootrect->y_min : pixelrect->y_min; pixelrect->y_max = (pixelrect->y_max < rootrect->y_max) ? rootrect->y_max : pixelrect->y_max; DisposeEnclRectData(rootdata); /* free(rootdata); */ return pixeldata; } double EnclRectAreaAttribute( void *pixeldata ) { EnclRectData *rectdata = pixeldata; return (double) ((rectdata->x_max - rectdata->x_min + 1) *(rectdata->y_max - rectdata->y_min + 1) ); } double EnclRectDiagAttribute( void *pixeldata ) { EnclRectData *rectdata = pixeldata; return (double) ( (rectdata->x_max - rectdata->x_min + 1)* (rectdata->x_max - rectdata->x_min + 1) + (rectdata->y_max - rectdata->y_min + 1)* (rectdata->y_max - rectdata->y_min + 1) ); } /**********************************************************************/ /* typedefs and functions for moment of inertia openings and closings */ /**********************************************************************/ typedef struct { int area; double sum_x, sum_y, sum_x2, sum_y2; } InertiaData; void *NewInertiaData( int x, int y ) { InertiaData *inertdata = (InertiaData *) malloc(sizeof(InertiaData)); inertdata->area=1; inertdata->sum_x=x; inertdata->sum_y=y; inertdata->sum_x2=x*x; inertdata->sum_y2=y*y; return ((void *) inertdata); } void DisposeInertiaData( void *inertdata ) { free(inertdata); } void AddToInertiaData( void *inertiadata, int x, int y ) { InertiaData *inertdata = (InertiaData *) inertiadata; inertdata->area ++; inertdata->sum_x += x; inertdata->sum_y += y; inertdata->sum_x2 += x*x; inertdata->sum_y2 += y*y; } void *MergeInertiaData( void *rootdata, void *pixeldata ) { InertiaData *rootinert = (InertiaData *) rootdata, *pixelinert = (InertiaData *) pixeldata; pixelinert->area += rootinert->area; pixelinert->sum_x += rootinert->sum_x; pixelinert->sum_y += rootinert->sum_y; pixelinert->sum_x2 += rootinert->sum_x2; pixelinert->sum_y2 += rootinert->sum_y2; free(rootdata); return pixeldata; } double InertiaAttribute ( void *pixeldata ) { InertiaData *inert = pixeldata; return inert->sum_x2 + inert->sum_y2 - (inert->sum_x * inert->sum_x + inert->sum_y * inert->sum_y) /(double)(inert->area) + (double)inert->area / 6.0; } /*********************************************************************/ IMAGE *attribute(IMAGE *im_miallib, int type, int oporclo, double lambdaVal, int graph) { int width, height; IMAGE *im_miallibout; width=GetImNx(im_miallib); height=GetImNy(im_miallib); CreateImages (im_miallib, &width, &height); auxdataext=CreateAuxData(width,height); im_miallibout=(IMAGE *)create_image(5, width, height, 1); if (im_miallibout==NULL){ fprintf(stderr, "Not enough memorey in *attribute\n"); FreeImages(); return NULL; } switch (type){ case 0: /* surface area */ if (oporclo==0){ GreyAttributeOpening (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewSurfaceData, DisposeSurfaceData, AddToSurfaceData, MergeSurfaceData, SurfaceAttribute, graph); } else{ GreyAttributeClosing (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewSurfaceData, DisposeSurfaceData, AddToSurfaceData, MergeSurfaceData, SurfaceAttribute, graph); } break; case 1: /* Inertia */ if (oporclo==0){ GreyAttributeOpening (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewInertiaData, DisposeInertiaData, AddToInertiaData, MergeInertiaData, InertiaAttribute, graph); } else{ GreyAttributeClosing (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewInertiaData, DisposeInertiaData, AddToInertiaData, MergeInertiaData, InertiaAttribute, graph); } break; case 2: /* Area of Enclose Rectangle */ if (oporclo==0){ GreyAttributeOpening (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewEnclRectData, DisposeEnclRectData, AddToEnclRectData, MergeEnclRectData, EnclRectAreaAttribute, graph); } else{ GreyAttributeClosing (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewEnclRectData, DisposeEnclRectData, AddToEnclRectData, MergeEnclRectData, EnclRectAreaAttribute, graph); } break; case 3: /* Length of diagonal of Enclose Rectangle */ if (oporclo==0){ GreyAttributeOpening (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewEnclRectData, DisposeEnclRectData, AddToEnclRectData, MergeEnclRectData, EnclRectAreaAttribute, graph); } else{ GreyAttributeClosing (lambdaVal, width, height, imext[0], parentext[0], auxdataext[0], NewEnclRectData, DisposeEnclRectData, AddToEnclRectData, MergeEnclRectData, EnclRectDiagAttribute, graph); } break; default: (void)sprintf(buf, "ERROR in Attribute(): \ invalid attribute type\n"); errputstr(buf); } WriteMialibIm(parentext, im_miallibout, width, height); FreeImages(); return im_miallibout; } /* This program computes the grey scale area opening. * The input is a grey scale image (im), and its output is * a grey-scale image (opening). * The time complexity of this algorithm is linear in the * number of pixels. * * (c) Arnold Meijster, Michael Wilkinson */ ByteImage imextarea; Image openingext; ByteImage ReadMialibImArea(IMAGE *im_miallib, int *width, int *height) { int i, j; ByteImage im; byte *buf; im = CreateByteImage (*width, *height); buf = (byte *)GetImPtr(im_miallib); for (i=0; i< *height; i++) for (j=0; j< *width; j++, buf++) im[i][j]= *buf; return im; } void CreateImagesArea(IMAGE *im_miallib, int *width, int *height) { imextarea = ReadMialibImArea (im_miallib, width, height); openingext = CreateImage (*width, *height); SortPixelsext = (int *)malloc ((*width)*(*height)*sizeof(int)); return; } /*************** Grey Scale Area Opening *****************/ void PixelUpSort(int size, byte *im, int *SortPixels) { int i, s, *idx[MAXGREYVAL], hist[MAXGREYVAL]; byte *tmp; /* first, we build a histogram */ for (i=0; i=0; i--) { idx[i] = SortPixels+s; s+=hist[i]; } /* Now we do the actual sorting */ for (i=0, tmp=im; i= 0) \ root = opening[root]; \ newroot = root; \ if (root!=pixel) { \ if ((-opening[root]) < lambdaVal) \ { \ opening[pixel] += opening[root]; \ opening[root] = pixel; \ newroot = pixel; \ } \ else \ opening[pixel] = -lambdaVal; \ } \ r = (p); \ while (r != root) \ { \ h=opening[r]; \ opening[r] = newroot; \ r = h; \ } \ } #define Link2(p) \ { \ root = (p); \ while (opening[root] >= 0) \ root = opening[root]; \ newroot = root; \ if (root!=pixel) { \ if ((im[root] == im[pixel]) || ((-opening[root]) < lambdaVal)) \ { \ opening[pixel] += opening[root]; \ opening[root] = pixel; \ newroot = pixel; \ } \ else \ opening[pixel] = -lambdaVal; \ } \ r = (p); \ while (r != root) \ { \ h=opening[r]; \ opening[r] = newroot; \ r = h; \ } \ } IMAGE *GreyAreaOpening4(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height, uplimit=(height-1)*width-1; greyval gval; int x, h, r, root,newroot,neigh; greyval *current; CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); if (im_miallibout==NULL){ fprintf(stderr, "Not enough memorey in GreyAreaOpening4\n"); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); return NULL; } /* Sort pixels first */ PixelDownSort (imsize, im, SortPixelsext); /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i= width) && (gval <= im[neigh=(pixel-width)])) Link2(neigh); if ((pixel <= uplimit) && (gval < im[neigh=(pixel+width)])) Link1(neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaOpening8(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height, uplimit=(height-1)*width-1; greyval gval; int x, h, r, root,newroot,neigh; greyval *current; int n5=-1-width; int n6=-width+1; int n7=width-1; int n8=width+1; // printf("coucou1 in GreyAreaOpening8\n"); CreateImagesArea(im_miallib, &width, &height); // printf("coucou2 in GreyAreaOpening8\n"); opening=openingext[0]; im=imextarea[0]; // printf("coucou3 in GreyAreaOpening8\n"); im_miallibout=(IMAGE *)create_image(5, width, height, 1); //printf("coucou4 in GreyAreaOpening8\n"); if (im_miallibout==NULL){ fprintf(stderr, "Not enough memory in GreyAreaOpening8\n"); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); return NULL; } /* Sort pixels first */ PixelDownSort (imsize, im, SortPixelsext); /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; iwidth) && (gval <= im[neigh=(pixel+n5)])) Link2 (neigh); if ((pixel <= uplimit) && (gval < im[neigh=(pixel+n7)])) Link1 (neigh); } if (xwidth) && (gval <= im[neigh=(pixel+n6)])) Link2 (neigh); if ((pixel < uplimit) && (gval < im[neigh=(pixel+n8)])) Link1 (neigh); } if ((pixel >= width) && (gval <= im[neigh=(pixel-width)])) Link2(neigh); if ((pixel <= uplimit) && (gval < im[neigh=(pixel+width)])) Link1(neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaOpening(IMAGE *im_miallib, int lambdaVal, int graph) { if (graph==4) return (GreyAreaOpening4 (im_miallib, lambdaVal)); else if (graph==8) return (GreyAreaOpening8 (im_miallib, lambdaVal)); else fprintf (stderr, "GreyAreaOpening: graph must be either 4 or 8\n"); return NULL; } IMAGE *GreyAreaClosing4(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height, uplimit=(height-1)*width-1; greyval gval; int x, h, r, root,newroot,neigh; greyval *current; CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); if (im_miallibout==NULL){ fprintf(stderr, "Not enough memorey in GreyAreaClosing4\n"); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); return NULL; } /* Sort pixels first */ PixelUpSort (imsize, im, SortPixelsext); /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i= im[neigh=(pixel-1)])) Link2 (neigh); if ((x < width-1) && (gval > im[neigh=(pixel+1)])) Link1 (neigh); if ((pixel >= width) && (gval >= im[neigh=(pixel-width)])) Link2(neigh); if ((pixel <= uplimit) && (gval > im[neigh=(pixel+width)])) Link1(neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaClosing8(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height, uplimit=(height-1)*width-1; greyval gval; int x, h, r, root,newroot,neigh; greyval *current; int n5=-1-width; int n6=-width+1; int n7=width-1; int n8=width+1; CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); if (im_miallibout==NULL){ fprintf(stderr, "Not enough memory in GreyAreaClosing8\n"); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); return NULL; } /* Sort pixels first */ PixelUpSort (imsize, im, SortPixelsext); /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i= im[neigh=(pixel-1)]) Link2 (neigh); if ((pixel>width) && (gval >= im[neigh=(pixel+n5)])) Link2 (neigh); if ((pixel <= uplimit) && (gval > im[neigh=(pixel+n7)])) Link1 (neigh); } if (x im[neigh=(pixel+1)]) Link1 (neigh); if ((pixel>width) && (gval >= im[neigh=(pixel+n6)])) Link2 (neigh); if ((pixel < uplimit) && (gval > im[neigh=(pixel+n8)])) Link1 (neigh); } if ((pixel >= width) && (gval >= im[neigh=(pixel-width)])) Link2(neigh); if ((pixel <= uplimit) && (gval > im[neigh=(pixel+width)])) Link1(neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaClosing(IMAGE *im_miallib, int lambdaVal, int graph) { if (graph==4) return (GreyAreaClosing4 (im_miallib, lambdaVal)); else if (graph==8) return (GreyAreaClosing8 (im_miallib, lambdaVal)); else fprintf (stderr, "GreyAreaClosing: graph must be either 4 or 8\n"); return NULL; } /*********************************************************************/ /*********************************************************************/ /**************** VERSION WITH ROI ********************/ /*********************************************************************/ /*********************************************************************/ int MAXROIVAL = 65534; /* pixels outside ROI should be at 255, image border MUST be at 255 !!! */ int OUTROI = 65535; extern ERROR_TYPE set_seq_shift(); void GreyAttributeClosingROI ( double lambdaVal, /* threshold on attribute */ int width, /* image width */ int height, /* image height */ greyval *im, /* input image */ greyval *parent, /* output image (also stores Tarjan trees) */ void **auxdata, /* auxilliary data for attributes */ /* last parameters are function pointers for creating, disposing, adding to, and merging auxilliary data, and computation of attribute */ void *(*NewAuxData)(int, int), void (*DisposeAuxData)(void *), void (*AddToAuxData)(void *,int, int), void *(*MergeAuxData)(void *, void*), double (*Attribute)(void *), int graph ) { int pixel, /* pixel coordinate in form width*y+x */ imsize=width*height, /* image size */ linkmade, /* keeps track of whether current pixel has been linked to any neighbour */ **idx=malloc(MAXGREYVAL * sizeof(int *)), /* list of pointers to sections of the SORTED pixels containing pixels of the same greylevel */ *start, *finish; /* start and finnish of current section */ greyval gval; /* current grey level */ int x, y, /* current pixel x and y */ h, r, root,newroot, /* auxilliary variables for root finding */ neigh; /* current neighbour */ greyval *current; /* pointer to current pixel */ long int shift[27]; /* array if offsets to neighbours */ int k; /* take graph into account */ if (set_seq_shift(width, height, 1, graph, shift) == ERROR) return ; /* Sort pixels first */ PixelSortforClosing (imsize, im, SortPixelsext, idx); finish=SortPixelsext; /* Forall pixels in increasing grey value and scan line order do Tarjan */ for (gval=0;gval im[neigh]) || (( neigh im[neigh]) || (( neigh= lambdaVal) ) /* and criterion met */ { parent[pixel] = DONE_ROOT; /* root is DONE_ROOT */ (*DisposeAuxData)( auxdata[pixel] ); /* get rid of auxilliary data */ } } /* Finnished one grey level */ } /* done building trees */ pixel = *(finish-1); if (parent[pixel] == ACTIVE_ROOT ) /* remove any remaining */ { parent[pixel] = DONE_ROOT; /* ACTIVE roots */ (*DisposeAuxData)( auxdata[pixel] ); } /* Forall pixels in reverse processing order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) parent[*current] = (parent[*current] < 0 ? im[*current] : parent[parent[*current]]); free(idx); return; } IMAGE *GreyAreaOpening4ROI(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height; greyval gval, val; int h, r, root,newroot,neigh; greyval *current; /* int n5=-1-width; */ /* int n6=-width+1; */ /* int n7=width-1; */ /* int n8=width+1; */ CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); /* Sort pixels first */ PixelDownSort (imsize, im, SortPixelsext); /* Forall pixels in decreasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaOpening8ROI(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height; greyval gval, val; int h, r, root,newroot,neigh; greyval *current; int n5=-1-width; int n6=-width+1; int n7=width-1; int n8=width+1; CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=(IMAGE *)create_image(5, width, height, 1); /* Sort pixels first */ PixelDownSort (imsize, im, SortPixelsext); /* Forall pixels in decreasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaOpeningROI(IMAGE *im_miallib, int lambdaVal, int graph) { if (graph==4) return (GreyAreaOpening4ROI (im_miallib, lambdaVal)); else if (graph==8) return (GreyAreaOpening8ROI (im_miallib, lambdaVal)); else fprintf (stderr, "GreyAreaOpening: graph must be either 4 or 8\n"); return NULL; } IMAGE *GreyAreaClosing4ROI(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height; greyval gval, val; int h, r, root,newroot,neigh; greyval *current; /* int n5=-1-width; */ /* int n6=-width+1; */ /* int n7=width-1; */ /* int n8=width+1; */ CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); /* Sort pixels first */ PixelUpSort (imsize, im, SortPixelsext); /* Forall pixels in decreasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i= val)) Link2 (neigh); val = im[neigh=(pixel+1)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); val = im[neigh=(pixel-width)]; if ((val != OUTROI) && (gval >= val)) Link2 (neigh); val = im[neigh=(pixel+width)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaClosing8ROI(IMAGE *im_miallib, int lambdaVal) { IMAGE *im_miallibout; int width=GetImNx(im_miallib); int height=GetImNy(im_miallib); greyval *opening; byte *im; int i, pixel,imsize=width*height; greyval gval, val; int h, r, root,newroot,neigh; greyval *current; int n5=-1-width; int n6=-width+1; int n7=width-1; int n8=width+1; CreateImagesArea(im_miallib, &width, &height); opening=openingext[0]; im=imextarea[0]; im_miallibout=create_image(5, width, height, 1); /* Sort pixels first */ PixelUpSort (imsize, im, SortPixelsext); /* Forall pixels in decreasing grey value and scan line order do Tarjan */ for (i=0,current=SortPixelsext; i= val)) Link2 (neigh); val = im[neigh=(pixel+1)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); val = im[neigh=(pixel-width)]; if ((val != OUTROI) && (gval >= val)) Link2 (neigh); val = im[neigh=(pixel+width)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); val = im[neigh=(pixel+n5)]; if ((val != OUTROI) && (gval >= val)) Link2 (neigh); val = im[neigh=(pixel+n6)]; if ((val != OUTROI) && (gval >= val)) Link2 (neigh); val = im[neigh=(pixel+n7)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); val = im[neigh=(pixel+n8)]; if ((val != OUTROI) && (gval > val)) Link1 (neigh); } /* Forall pixels in (increasing greyscale,scan line) order do Resolve */ for (current=&SortPixelsext[imsize-1]; current>=SortPixelsext; current--) opening[*current] = (opening[*current] < 0 ? im[*current] : opening[opening[*current]]); WriteMialibIm(openingext, im_miallibout, width, height); free(openingext[0]); free(openingext); free(imextarea[0]); free(imextarea); free(SortPixelsext); return im_miallibout; } IMAGE *GreyAreaClosingROI(IMAGE *im_miallib, int lambdaVal, int graph) { if (graph==4) return (GreyAreaClosing4ROI (im_miallib, lambdaVal)); else if (graph==8) return (GreyAreaClosing8ROI (im_miallib, lambdaVal)); else fprintf (stderr, "GreyAreaClosingROI: graph must be either 4 or 8\n"); return NULL; } /*@}*/ jeolib-miallib-1.1.6/core/c/vectorize.c000066400000000000000000000130441467232417700177410ustar00rootroot00000000000000/*********************************************************************** Author(s): Dominik Brunner Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** vectorize.c - description ------------------- Vectorize multispectral high resolution satellite images. Output file formats are Scalabale Vector Graphics (SVG) and/or ESRI Shapefiles begin : Fri May 14 2004 ***************************************************************************/ #include #include #define NO_BUF #include "borderdetection.h" #include "writeSVG.h" #include "writeShapeFile.h" #include "base.h" #include "mslabel.h" #include "determineSize.h" #include "simplifyLine.h" /** \addtogroup group_seg * @{ */ /* * vectorizeImage: Vectorize multispectral satellite images. Output file format is SVG and/or * ESRI Shapefiles * * Parameters: * * imap array of pointer to the channels of an input images * * nc size of imap => number of channels * * filename filename to the input image (is needed in order to read the geo informations, if available) * * format Output vector file format * 0 (don't vectorize) * 1 (SVG) * 2 (ESRI Shapefile) * 3 (SVG and ESRI Shapefile) * * simplifyBorderLines * the bigger the value, the more simplified are the border lines. * A value of 0 means no simplification * * Return values: * * NO_ERROR if everything is ok * * ERROR if error occured */ #include "uc_def.h" ERROR_TYPE vectorizeImage(IMAGE **imap, int nc, char *filename, int format, double simplifyBorderLines) { int i; long int regionNumber, r, crtLabel; IMAGE * labelIm; struct REGION ** regions; struct LINEPOOL linepool; LBL_TYPE * pLabelIm; PIX_TYPE * pInputIm; printf("vectorize() - start vectorisation \n"); for (i = 0; i < nc; i++){ if ((GetImNx(imap[0]) != GetImNx(imap[i])) \ || (GetImNy(imap[0]) != GetImNy(imap[i])) \ || (GetImDataType(imap[i]) != t_UCHAR)){ printf("Datatype not provided, or dimensions of image different!"); return ERROR; } } labelIm = (IMAGE *) create_image(t_LBL_TYPE, GetImNx(imap[0]), GetImNy(imap[0]), 1); if (labelIm==NULL){ return ERROR; } //labelImage if(labelImage(imap, nc, labelIm, 4, 0)==NULL){ free_image(labelIm); return ERROR; } pLabelIm = (LBL_TYPE *) GetImPtr(labelIm); //determineSize if((regionNumber = thresholdRegion_Size(labelIm, 1))==ERROR){ free_image(labelIm); return ERROR; } //initialize Regions if((regions=calloc(regionNumber+1, sizeof(struct REGION *)))==NULL){ printf("Not enough memory!!! - detectBorders()\n"); return ERROR; } for(r=0; r=0; --r){ printf("Not enough memory!!! - detectBorders()\n"); freeRegion(regions[r]); free(regions[r]); } return ERROR; } if(!(initRegion(regions[r],10, 100, nc))){ printf("Not enough memory!!! - detectBorders()\n"); for(; r>=0; --r){ printf("Not enough memory!!! - detectBorders()\n"); freeRegion(regions[r]); free(regions[r]); } return ERROR; } } if(!(initLinePool(&linepool, 500))){ for(r=0; rcolorValues[i]=pInputIm[r]; } } //make border detection if(detectBorders(labelIm, regions, regionNumber, &linepool)==ERROR){ for(r=0; r0){ simplifyLine(&linepool, simplifyBorderLines, GetImNx(imap[0]), GetImNy(imap[0])); } if(format==1 || format==3){ if(writeSVG(regions, regionNumber, filename, GetImNx(imap[0]), GetImNy(imap[0]))==ERROR){ for(r=0; r. ***********************************************************************/ /*************************************************************************** vectorize.c - description ------------------- Vectorize multispectral high resolution satellite images. Output file formats are Scalabale Vector Graphics (SVG) and/or ESRI Shapefiles begin : Fri May 14 2004 ***************************************************************************/ #include #include #include "borderdetection.h" #include "writeSVG.h" #include "writeShapeFile.h" #include "base.h" #include "mslabel.h" #include "determineSize.h" #include "simplifyLine.h" /* * vectorizeImage: Vectorize multispectral satellite images. Output file format is SVG and/or * ESRI Shapefiles * * Parameters: * * imap array of pointer to the channels of an input images * * nc size of imap => number of channels * * filename filename to the input image (is needed in order to read the geo informations, if available) * * format Output vector file format * 0 (don't vectorize) * 1 (SVG) * 2 (ESRI Shapefile) * 3 (SVG and ESRI Shapefile) * * simplifyBorderLines * the bigger the value, the more simplified are the border lines. * A value of 0 means no simplification * * Return values: * * NO_ERROR if everything is ok * * ERROR if error occured */ #include "uc_def.h" ERROR_TYPE vectorizeImage(IMAGE **imap, int nc, char *filename, int format, double simplifyBorderLines){ int i; long int regionNumber, r, crtLabel; IMAGE * labelIm; struct REGION ** regions; struct LINEPOOL linepool; int box[6]; LBL_TYPE * pLabelIm; PIX_TYPE * pInputIm; // initilize box for frame which shall be added in order to solve // problem with neighbours box[0] = 1; box[1] = 1; box[2] = 1; box[3] = 1; box[4] = 0; box[5] = 0; printf("vectorize() - start vectorisation \n"); for (i = 0; i < nc; i++){ if ((GetImNx(imap[0]) != GetImNx(imap[i])) \ || (GetImNy(imap[0]) != GetImNy(imap[i])) \ || (GetImDataType(imap[i]) != t_UCHAR)){ printf("Datatype not provided, or dimensions of image different!"); return ERROR; } } labelIm = (IMAGE *) create_image(t_LBL_TYPE, GetImNx(imap[0]), GetImNy(imap[0]), 1); if (labelIm==NULL){ return ERROR; } //labelImage if(labelImage(imap, nc, labelIm, 4, 0)==NULL){ free_image(labelIm); return ERROR; } pLabelIm = (LBL_TYPE *) GetImPtr(labelIm); //determineSize if((regionNumber = thresholdRegion_Size(labelIm, 1))==ERROR){ free_image(labelIm); return ERROR; } //initialize Regions if((regions=calloc(regionNumber+1, sizeof(struct REGION *)))==NULL){ printf("Not enough memory!!! - detectBorders()\n"); return ERROR; } for(r=0; r=0; --r){ printf("Not enough memory!!! - detectBorders()\n"); freeRegion(regions[r]); free(regions[r]); } return ERROR; } if(!(initRegion(regions[r],10, 100, nc))){ printf("Not enough memory!!! - detectBorders()\n"); for(; r>=0; --r){ printf("Not enough memory!!! - detectBorders()\n"); freeRegion(regions[r]); free(regions[r]); } return ERROR; } } if(!(initLinePool(&linepool, 500))){ for(r=0; rcolorValues[i]=pInputIm[r]; } } //make border detection if(detectBorders(labelIm, regions, regionNumber, &linepool)==ERROR){ for(r=0; r0){ simplifyLine(&linepool, simplifyBorderLines, GetImNx(imap[0]), GetImNy(imap[0])); } if(format==1 || format==3){ if(writeSVG(regions, regionNumber, filename, GetImNx(imap[0]), GetImNy(imap[0]))==ERROR){ for(r=0; r. ***********************************************************************/ /*************************************************************************** writeSVG.c - description ------------------- Vectorizes the boundary lines from the region. The output file format is SVG. The geoinformations will be considered for the output (if available) begin : Fri May 14 2004 ***************************************************************************/ #include #include #include #define NO_BUF #include "borderdetection.h" #include "writeSVG.h" #include "miallib.h" #include "base.h" #include #include /* * writeSVG: write the boundary lines o fregions as SVG * * Parameters: * * regions REGIONS with their exact boundary line segments * * regionNumber size of regions array => number of regions * * filename filename to the input image (is needed in order to read the geo informations, if available) * * width width of image (needed to make e.g. viewport settings in SVG) * * height height of image (needed to make e.g. viewport settings in SVG) * * Return values: * * NO_ERROR if everything is ok * * ERROR if error occured */ ERROR_TYPE writeSVG(struct REGION ** regions, int regionNumber, char * fileName, int width, int height) { char buffer[200], outputFName[1000]; long int crtPos; int i; gzFile gzFhd; TIFF *tif=(TIFF*)0; GTIF *gtif=(GTIF*)0; /* GeoKey-level descriptor */ double x=0, y=0; double widthPCS, heightPCS, widthPCSZero, heightPCSZero; GDALDatasetH hDataset; char *pszProjection; strncpy( outputFName, fileName, sizeof(outputFName)-4 ); for( i = strlen(outputFName)-1; i > 0; i-- ) { if( outputFName[i] == '.' ) { strcpy( outputFName + i, ".svgz" ); break; } } if( i <= 0 ) strcat( outputFName, ".svgz" ); printf("write SVG file: %s", outputFName); //open geotiff => use for vectorization geo information tif=XTIFFOpen(fileName,"r"); gtif = GTIFNew(tif); if(!gtif) gtif=NULL; if(!GTIFImageToPCS(gtif, &x, &y)){ gtif=NULL; } crtPos=SEED; gzFhd=gzopen(outputFName, "w"); sprintf(buffer, "\n"); gzputs(gzFhd, buffer); sprintf(buffer, "\n"); gzputs(gzFhd, buffer); if(gtif!=NULL){ widthPCSZero = 0; heightPCSZero = 0; GTIFImageToPCS(gtif, & widthPCSZero, & heightPCSZero); sprintf(buffer, "\n", fabs(widthPCS-widthPCSZero), fabs(heightPCS-heightPCSZero)); gzputs(gzFhd, buffer); sprintf(buffer, "\n"); gzputs(gzFhd, buffer); }else{ sprintf(buffer, "\n", width, height); gzputs(gzFhd, buffer); sprintf(buffer, "\n"); gzputs(gzFhd, buffer); } //write projection information if available GDALAllRegister(); hDataset = GDALOpen( fileName, GA_ReadOnly ); if( hDataset != NULL ){ if( GDALGetProjectionRef( hDataset ) != NULL ){ pszProjection = (char *) GDALGetProjectionRef( hDataset ); if(pszProjection[0]!=0){ sprintf(buffer, "\n"); gzputs(gzFhd, buffer); gzputs(gzFhd, pszProjection); sprintf(buffer, "\n\n"); gzputs(gzFhd, buffer); } } GDALClose( hDataset ); } for(; crtPos\n\n"); gzputs(gzFhd, buffer); gzclose(gzFhd); if(gtif) GTIFFree(gtif); if(tif) XTIFFClose(tif); return NO_ERROR; } /* * writeSVGPolygon: output function for vectorizing one region * * Parameters: * * region REGION with its exact boundary line segments * * gzFhd file handler to gZip file (for outputting the SVG) * * gtif file handler to GeoTiff file. If it is NULL, * the output will be made without geoinformations * (without georeferenzing image coordiantes) * * Return values: * * NO_ERROR if everything is ok * * ERROR if error occured */ ERROR_TYPE writeSVGPolygon(struct REGION * region, gzFile gzFhd, GTIF *gtif) { //go on here char buffer[200]; int i, abool=1, * trace; struct LINE * line, ** lineArray; struct POINT * firstPoint, * crtPoint, * newPoint; int * colorValues; colorValues=region->colorValues; double x,y; if(region->channelSize==3){ /*ORIGINAL sprintf(buffer, "channelSize==1){ sprintf(buffer, "crtPos); for(i=0; icrtPos;i++){ trace[i]=0; } trace[0]=1; line = region->lines[0]; firstPoint=line->points[0]; for(i=0; icrtPos; i++){ if(line->points[i]->useFlag){ if(gtif!=NULL){ x=(double) line->points[i]->x; y=(double) line->points[i]->y; if(GTIFImageToPCS(gtif, &x, &y)){ sprintf(buffer, "%11.3f,%11.3f ", x ,y); } }else{ sprintf(buffer, "%i,%i ", (line->points[i]->x) ,(line->points[i]->y)); } gzputs(gzFhd, buffer); } } crtPoint=line->points[line->crtPos-1]; while(abool){ newPoint=getNextPoint(region, crtPoint, trace); if(newPoint==NULL){ break; } //line = getLineSegment(region, crtPoint, newPoint); lineArray = getLineSegment(region, crtPoint, newPoint); if(lineArray[1]!=NULL){ line = lineArray[1]; }else{ line = lineArray[0]; } free(lineArray); //check in which direction the values must be read! if(arePointsEqual(crtPoint, line->points[0])){ for(i=1; icrtPos-1; i++){ if(line->points[i]->useFlag){ if(gtif!=NULL){ x=(double) line->points[i]->x; y=(double) line->points[i]->y; if(GTIFImageToPCS(gtif, &x, &y)){ sprintf(buffer, "%11.3f,%11.3f ", x ,y); } }else{ sprintf(buffer, "%i,%i ", (line->points[i]->x) ,(line->points[i]->y)); } gzputs(gzFhd, buffer); } } }else{ for(i=line->crtPos-2; i>0; i--){ if(line->points[i]->useFlag){ if(gtif!=NULL){ x=(double) line->points[i]->x; y=(double) line->points[i]->y; if(GTIFImageToPCS(gtif, &x, &y)){ sprintf(buffer, "%11.3f,%11.3f ", x ,y); } }else{ sprintf(buffer, "%i,%i ", (line->points[i]->x) ,(line->points[i]->y)); } gzputs(gzFhd, buffer); } } } if(arePointsEqual(newPoint, firstPoint)){ abool=0; }else{ if(line->points[i]->useFlag){ if(gtif!=NULL){ x=(double) newPoint->x; y=(double) newPoint->y; if(GTIFImageToPCS(gtif, &x, &y)){ sprintf(buffer, "%11.3f,%11.3f ", x ,y); } }else{ sprintf(buffer, "%i,%i ", (newPoint->x) ,(newPoint->y)); } gzputs(gzFhd, buffer); } crtPoint=newPoint; } //sprintf(buffer, "%i,%i ", (crtPoint->x)-1 ,(crtPoint->y)-1); } sprintf(buffer, "\">\n"); gzputs(gzFhd, buffer); if(!(region->channelSize==1 || region->channelSize==3)){ sprintf(buffer, "\n"); gzputs(gzFhd, buffer); for(i=0; ichannelSize;i++){ sprintf(buffer, "\n", i+1, colorValues[i]); gzputs(gzFhd, buffer); } sprintf(buffer, "\n"); gzputs(gzFhd, buffer); } sprintf(buffer,"\n"); gzputs(gzFhd, buffer); free(trace); return NO_ERROR; } ��������������������������������������������������������������������������������������������������������jeolib-miallib-1.1.6/core/c/writeSVG.h��������������������������������������������������������������0000664�0000000�0000000�00000002721�14672324177�0017446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** writeSVG.h - description ------------------- begin : Fri May 14 2004 ***************************************************************************/ #ifndef init_writeSVG #define init_writeSVG #include "borderdetection.h" #include #include ERROR_TYPE writeSVGPolygon(struct REGION * region, gzFile fhd, GTIF *gtif); ERROR_TYPE writeSVG(struct REGION ** regions, int regionNumber, char * fileName, int width, int height); #endif �����������������������������������������������jeolib-miallib-1.1.6/core/c/writeShapeFile.c��������������������������������������������������������0000664�0000000�0000000�00000022163�14672324177�0020644�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** writeShapeFile.c - description ------------------- Vectorizes the boundary lines from the region. The output file format is ESRI Shapefile. The geoinformations will be considered for the output (if available) begin : Mon May 24 2004 ***************************************************************************/ #include #include #include "borderdetection.h" #include "writeShapeFile.h" #include "miallib.h" #include "base.h" #include #include /* * writeSVG: Write the defining matrix for this file to a .tfw (Tiff world) file with the same * basename. * * Parameters: * * * gtif file handler to GeoTiff file. * * filename filename to the input image * * Return values: * * none */ static void WriteTFWFile( GTIF * gtif, const char * tif_filename ) { char tfw_filename[1024]; int i; double adfCoeff[6], x, y; FILE *fp; if (gtif==NULL){ return; } /* * form .tfw filename */ strncpy( tfw_filename, tif_filename, sizeof(tfw_filename)-4 ); for( i = strlen(tfw_filename)-1; i > 0; i-- ) { if( tfw_filename[i] == '.' ) { strcpy( tfw_filename + i, ".tfw" ); break; } } if( i <= 0 ) strcat( tfw_filename, ".tfw" ); printf("write TFW file: %s", tfw_filename); /* * Compute the coefficients. */ x = 0.5; y = 0.5; if( !GTIFImageToPCS( gtif, &x, &y ) ) return; adfCoeff[4] = x; adfCoeff[5] = y; x = 1.5; y = 0.5; if( !GTIFImageToPCS( gtif, &x, &y ) ) return; adfCoeff[0] = x - adfCoeff[4]; adfCoeff[1] = y - adfCoeff[5]; x = 0.5; y = 1.5; if( !GTIFImageToPCS( gtif, &x, &y ) ) return; adfCoeff[2] = x - adfCoeff[4]; adfCoeff[3] = y - adfCoeff[5]; /* * Write out the coefficients. */ fp = fopen( tfw_filename, "wt" ); if( fp == NULL ) { perror( "fopen" ); fprintf( stderr, "Failed to open TFW file `%s'\n", tfw_filename ); return; } for( i = 0; i < 6; i++ ) fprintf( fp, "%24.10f\n", adfCoeff[i] ); fclose( fp ); } /* * writeShapeFile: write the boundary lines of regions as ESRI Shapefile * * Parameters: * * regions REGIONS with their exact boundary line segments * * regionNumber size of regions array => number of regions * * filename filename to the input image (is needed in order to read the geo informations, if available) * * Return values: * * NO_ERROR if everything is ok * * ERROR if error occured */ ERROR_TYPE writeShapeFile(struct REGION ** regions, int regionNumber, char * fileName) { long int crtPos; double x=0, y=0; int i, * channels, channelSize, shapeNumber; char buffer[50], prjFilename[1024]; TIFF *tif=(TIFF*)0; GTIF *gtif=(GTIF*)0; /* GeoKey-level descriptor */ GDALDatasetH hDataset; char *pszProjection; FILE * prjFhd; SHPHandle shpHdl; DBFHandle dbfHdl; SHPObject * shpObject; printf("write Shapefiles\n"); shpHdl = SHPCreate(fileName, SHPT_POLYGON); dbfHdl = DBFCreate(fileName); //open geotiff tif=XTIFFOpen(fileName,"r"); if (tif==NULL){ (void)sprintf(buf,"ERROR in writeShapeFile(): invalid GeoTIFF file name \"%s\" \n", fileName); errputstr(buf); return ERROR; } gtif = GTIFNew(tif); if(!gtif) gtif=NULL; if(!GTIFImageToPCS(gtif, &x, &y)){ gtif=NULL; } if(gtif!=NULL) WriteTFWFile(gtif, fileName); crtPos=SEED; channelSize = regions[crtPos]->channelSize; channels = calloc(channelSize, sizeof(int)); for(i=0; icolorValues[i]); } } SHPClose(shpHdl); DBFClose(dbfHdl); if(gtif) GTIFFree(gtif); if(tif) XTIFFClose(tif); //write prj file GDALAllRegister(); hDataset = GDALOpen( fileName, GA_ReadOnly ); if( hDataset != NULL ){ if( GDALGetProjectionRef( hDataset ) != NULL ){ pszProjection = (char *) GDALGetProjectionRef( hDataset ); if(pszProjection[0]!=0){ //form prj filename strncpy( prjFilename, fileName, sizeof(prjFilename)-4 ); for( i = strlen(prjFilename)-1; i > 0; i-- ) { if( prjFilename[i] == '.' ) { strcpy( prjFilename + i, ".prj" ); break; } } if( i <= 0 ) strcat( prjFilename, ".prj" ); printf("write PRJ file: %s", prjFilename); prjFhd=fopen(prjFilename, "w"); fputs(pszProjection, prjFhd); fclose(prjFhd); } } GDALClose( hDataset ); } return NO_ERROR; } /* * writeSHPPolygon: output function for vectorizing one region * * Parameters: * * region REGION with its exact boundary line segments * * id unique id with which shape object will be generated * * gtif file handler for GeoTiff file. If it is NULL, * the output will be made without geoinformations * (without georeferenzing image coordiantes) * * Return values: * * Shape object if everything is ok * * NULL if error occured */ SHPObject * writeSHPPolygon(struct REGION * region, int id, GTIF * gtif){ //go on here int i, abool=1, * trace; struct LINE * line, ** lineArray,* hLine; struct POINT * firstPoint, * crtPoint, * newPoint; double * xVertices, * yVertices; hLine = (struct LINE *) malloc(sizeof(struct LINE)); initLine(hLine, 100); SHPObject * shpObject = NULL; trace=(int *) calloc(sizeof(int), region->crtPos); for(i=0; icrtPos;i++){ trace[i]=0; } trace[0]=1; line = region->lines[0]; firstPoint=line->points[0]; for(i=0; icrtPos; i++){ if(line->points[i]->useFlag){ if(addPointToLine(hLine, line->points[i])==NULL){ freeLine(hLine); return NULL; } } } crtPoint=line->points[line->crtPos-1]; while(abool){ newPoint=getNextPoint(region, crtPoint, trace); if(newPoint==NULL){ abool=0; break; } //line = getLineSegment(region, crtPoint, newPoint); lineArray = getLineSegment(region, crtPoint, newPoint); if(lineArray[1]!=NULL){ line = lineArray[1]; }else{ line = lineArray[0]; } free(lineArray); //check in which direction the values must be read! if(arePointsEqual(crtPoint, line->points[0])){ for(i=1; icrtPos-1; i++){ if(line->points[i]->useFlag){ if(addPointToLine(hLine, line->points[i])==NULL){ freeLine(hLine); return NULL; } } } }else{ for(i=line->crtPos-2; i>0; i--){ if(line->points[i]->useFlag){ if(addPointToLine(hLine, line->points[i])==NULL){ freeLine(hLine); return NULL; } } } } if(arePointsEqual(newPoint, firstPoint)){ abool=0; if(line->points[i]->useFlag){ addPointToLine(hLine, newPoint); } }else{ if(line->points[i]->useFlag){ if(addPointToLine(hLine, line->points[i])==NULL){ freeLine(hLine); return NULL; } } crtPoint=newPoint; } } //now all points for the polygon are collected xVertices = calloc (hLine->crtPos, sizeof(double)); yVertices = calloc (hLine->crtPos, sizeof(double)); if(!xVertices || ! yVertices){ printf("not enough memory!!!"); return NULL; } for(i=0;icrtPos;i++){ crtPoint=hLine->points[i]; xVertices[i]=crtPoint->x; yVertices[i]=crtPoint->y; if(gtif!=NULL){ GTIFImageToPCS(gtif, & xVertices[i], &yVertices[i]); } } shpObject = SHPCreateObject(SHPT_POLYGON, id, 0, NULL,NULL, i, xVertices, yVertices, NULL, NULL); free(trace); free(xVertices); free(yVertices); free(hLine->points); free(hLine); return shpObject; } �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������jeolib-miallib-1.1.6/core/c/writeShapeFile.h��������������������������������������������������������0000664�0000000�0000000�00000002717�14672324177�0020654�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*********************************************************************** Author(s): Dominik Brunner and Pierre Soille Copyright (C) 2004-2020 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ /*************************************************************************** writeShapeFile.h - description ------------------- begin : Thu May 27 2004 ***************************************************************************/ #ifndef init_writeShapeFile #define init_writeShapeFile #include "borderdetection.h" #include #include ERROR_TYPE writeShapeFile(struct REGION ** regions, int regionNumber, char * fileName); SHPObject * writeSHPPolygon(struct REGION * region, int id, GTIF * gtif); #endif �������������������������������������������������jeolib-miallib-1.1.6/core/c/wsfah.c�����������������������������������������������������������������0000664�0000000�0000000�00000061756�14672324177�0017054�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*********************************************************************** Author(s): Pierre Soille Copyright (C) 2000-2022 European Union (Joint Research Centre) This file is part of miallib. miallib is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. miallib is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with miallib. If not, see . ***********************************************************************/ #include #include #include "miallib.h" #include "fah.h" #include "fifo.h" #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #ifndef max #define max(a,b) ((a)>(b)?(a):(b)) #endif extern IMAGE *pixsort(IMAGE *im, IMAGE *imrsum); /** \addtogroup group_seg * @{ */ #define PIX_TYPE unsigned char #define LABEL_TYPE unsigned char #define LABEL_MAX 0x7F #define LABEL_MSB 0x80 ERROR_TYPE uc_uc_wsfah(unsigned char *iml, unsigned char *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE, August 1993 ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ long int k, ofs, ofsk; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; long int i, shftk, npix; npix = (long int)nx*(long int)ny*(long int)nz; maxfl++; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("wsfah(): not enough memory for the FAH\n"); return -9; } /* create maxfl queues */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i 32767 */ #define PIX_TYPE unsigned char #define LABEL_TYPE UINT32 #define LABEL_MAX 0x7FFFFFFF #define LABEL_MSB 0x80000000 ERROR_TYPE uc_u32_wsfah(UINT32 *iml, unsigned char *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE, August 1993 ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ long int k, ofs, ofsk; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; long int i, shftk, npix; int nshfttmp=0; // NEW int flag = 0; // NEW npix = (long int)nx*(long int)ny*(long int)nz; maxfl++; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("wsfah(): not enough memory for the FAH\n"); return -9; } /* create maxfl queues */ for (i=0; i0)&&(*pl0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i 32767 */ #define PIX_TYPE unsigned short #define LABEL_TYPE UINT32 #define LABEL_MAX 0x7FFFFFFF #define LABEL_MSB 0x80000000 ERROR_TYPE us_u32_wsfah(UINT32 *iml, unsigned short *imr, int nx, int ny, int nz, long int *shft, int nshft, int maxfl) { /* ** author: Pierre SOILLE, August 1993 ** iml: pointer to an image of labels whith LABEL_MAX valued border ** imr: pointer to a reference image ** nx: number of columns ** ny: number of lines ** nz: number of planes (1 for 2D images) ** shft: shift array to access the neighbours of a pixel ** nshft: number of shifts ** maxfl: maximum level for the immersion simulation */ long int k, ofs, ofsk; LABEL_TYPE *pl; PIX_TYPE *pr; FIFO **fah, *pq; long int i, shftk, npix; int nshfttmp=0; // NEW on 8-3-2007 int flag = 0; // NEW npix = (long int)nx*(long int)ny*(long int)nz; maxfl++; /* Create an array of FIFOs */ if ((fah = (FIFO **)calloc(maxfl, sizeof(FIFO *))) == NULL){ (void) printf("wsfah(): not enough memory for the FAH\n"); return -9; } /* create maxfl queues */ for (i=0; i0)&&(*pl0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; i0)&&(*plLABEL_MAX) *pl ^= LABEL_MSB; /* here we go */ for (i=0; iLABEL_MAX) *pl ^= LABEL_MSB; clear_fifo(pq); } free(fah); free(shft); return NO_ERROR; } #undef PIX_TYPE #undef LABEL_TYPE #undef LABEL_MAX #undef LABEL_MSB ERROR_TYPE skelfah(IMAGE *iml, IMAGE *imr, IMAGE *imdir, int graph, int maxfl) { /* ** author: Pierre SOILLE, August 1993 ** iml: image of labels with a border = LABEL_MAX ** imr: reference image with border ** imdir: image of directions of flooding ** graph: connectivity ** maxfl: maximum immersion level ** comment: outputs only direction of flooding so far */ long int *shft; shft = (long int *)calloc(graph,sizeof(long int)); set_seq_shift(GetImNx(iml), GetImNy(iml), GetImNz(iml), graph, shft); /* here we go */ switch (GetImDataType(imr)){ case t_UCHAR: return(uc_skelfah((unsigned short *)(GetImPtr(iml)), (unsigned char*)(GetImPtr(imr)), (unsigned char*)(GetImPtr(imdir)), GetImNx(iml), GetImNy(iml), GetImNz(iml), shft, graph, maxfl)); break; default: (void)sprintf(buf, "ERROR in wsfah(): \ invalid ImDataType\n"); errputstr(buf); free(shft); return(ERROR); } } #include "us_def.h" ERROR_TYPE us_skelfah2(IMAGE *imc, IMAGE *impskp, int n, int graph) { int i,j,k,nsx,x; long int *shft1, *shft2; IMAGE *swin; PIX_TYPE *pccrt, *pcrt, cval; UCHAR *ppskp; UCHAR *pswin, *pswincrt, *ucp, code, maxval, bor,border; FIFO4 *q1, *q2; int box[BOXELEM]; long int nx, ny, npix, offset; IMAGE *imhst, *imrsum, *imsort; USHORT **pl; /* Compute cumulated histogram */ imhst = (IMAGE *)histo1d(imc); if (imhst==NULL) return(ERROR); imrsum = (IMAGE*)rsum(imhst); free_image(imhst); if (imrsum==NULL) return(ERROR); /* Sort pointers to buf_n in an increasing order of its gray levels */ imsort = pixsort(imc, imrsum); if (imsort==NULL) return(ERROR); BOX_2D; q1 = create_fifo4(n+2); q2 = create_fifo4(n+2); swin = create_image(t_UCHAR, 2*n+1, 2*n+1, 1); if (swin==NULL) return(ERROR); shft1 = (long int *)calloc(graph,sizeof(long int)); shft2 = (long int *)calloc(graph,sizeof(long int)); nx = GetImNx(imc); ny = GetImNy(imc); set_seq_shift(nx, ny, GetImNz(imc), graph, shft1); set_seq_shift(2*n+1, 2*n+1, 1, graph, shft2); pccrt=(PIX_TYPE *)GetImPtr(imc); ppskp=(UCHAR *)GetImPtr(impskp); pswin=(UCHAR *)GetImPtr(swin); npix=GetImNPix(impskp); pl=(USHORT**)GetImPtr(imsort); for (i=0; i. ***********************************************************************/ /** @file * Watershed computation by immersion simulation \cite soille-vincent90 see also \cite vincent-soille91 * @author Pierre Soille */ #include #include #include "miallib.h" #include "fifo.h" /** @defgroup group_seg Segmentation * Functions dealing with image segmentation * @{ */ /* ** Function to sort pointers to an input array of n pixels in an ** increasing order of their value. Processing time is in O(n). ** Distributive sort. */ #include "uc_def.h" IMAGE *uc_pixsort(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim, **psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_PTR, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (PIX_TYPE **)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "uc_undef.h" #include "u32_def.h" IMAGE *u32_pixsort(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim, **psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_PTR, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (PIX_TYPE **)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "u32_undef.h" #include "us_def.h" IMAGE *us_pixsort(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim, **psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_PTR, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (PIX_TYPE **)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_pixsort(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim, **psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_PTR, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (PIX_TYPE **)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "i32_undef.h" /*! * @param im an IMAGE pointer argument. * @param imrsum an IMAGE pointer argument holding the running sum of the histogram of the values in im. Sort the image pixels in increasing order of their pixel value and output an array of pointers to the sorted pixel values. */ IMAGE *pixsort(IMAGE *im, IMAGE *imrsum) { switch (GetImDataType(im)){ case t_UCHAR: return(uc_pixsort(im, imrsum)); break; case t_USHORT: return(us_pixsort(im, imrsum)); break; case t_INT32: return(i32_pixsort(im, imrsum)); break; case t_UINT32: return(u32_pixsort(im, imrsum)); break; default: (void)sprintf(buf,"pixsort(): invalid pixel type\n"); errputstr(buf); } return(NULL); } #ifndef NO_generic_IMAGE #include "g_def.h" IMAGE *generic_sort_offset(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim; UINT32 *psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_UINT32, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (UINT32 *)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "g_undef.h" #endif /* #ifndef NO_generic_IMAGE */ #include "us_def.h" IMAGE *us_sort_offset(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim; UINT32 *psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_UINT32, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (UINT32 *)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "us_undef.h" #include "i32_def.h" IMAGE *i32_sort_offset(IMAGE *im, IMAGE *imrsum) { IMAGE *imsort; PIX_TYPE *pim; UINT32 *psort; HST1D_TYPE *prsum; unsigned i, npix = GetImNPix(im); imsort = create_image(t_UINT32, GetImNx(im), GetImNy(im), GetImNz(im)); if (imsort==NULL) return(NULL); psort = (UINT32 *)GetImPtr(imsort); prsum = (HST1D_TYPE *)GetImPtr(imrsum); pim = (PIX_TYPE *)GetImPtr(im); for (i=0; i0; i--) prsum[i] = prsum[i-1]; prsum[0] = 0; return(imsort); } #include "i32_undef.h" IMAGE *sort_offset(IMAGE *im, IMAGE *imrsum) { switch (GetImDataType(im)){ #ifndef NO_generic_IMAGE case t_GENERIC: return(generic_sort_offset(im, imrsum)); break; #endif #ifndef NO_uc_IMAGE case t_UCHAR: return(uc_sort_offset(im, imrsum)); break; #endif case t_USHORT: return(us_sort_offset(im, imrsum)); break; case t_INT32: return(i32_sort_offset(im, imrsum)); break; default: (void)sprintf(buf,"sort_offset(): invalid pixel type\n"); errputstr(buf); } return(NULL); } #include "us_def.h" #define INQUEUE PIX_MAX-1 #define WINIT PIX_MAX-2 #define MASK PIX_MAX-3 #define WSHED PIX_MAX-4 ERROR_TYPE us_flood1(IMAGE *im, IMAGE *hst, IMAGE *srtim, int graph) { PIX_TYPE *pim, *pcrt, *pend, *ptr, *p, **psrt, lbl = 0; HST1D_TYPE *phst; FIFO4 *q; long int i, j, k, nlev, shift[27], npix; int flag = FALSE; pim = (PIX_TYPE *)GetImPtr(im); npix = GetImNPix(im); /* set to WINIT input image */ pend = pim + npix; for (pcrt = pim; pcrt < pend;) *pcrt++ = WINIT; /* create a queue */ q = create_fifo4(npix/100L); if (q == NULL){ (void) sprintf(buf, "us_flood1(): not enough memory"); errputstr(buf); return ERROR; } /* take graph into account */ if (set_seq_shift(GetImNx(im), GetImNy(im), GetImNz(im), graph, shift) == ERROR) return ERROR; /* here we go */ nlev = GetImNx(hst)-1; phst = (HST1D_TYPE *)GetImPtr(hst); psrt = (PIX_TYPE **)GetImPtr(srtim); for (i = 1; i < nlev; ++i){ /* geodesic SKIZ of level Li-1 inside level Li */ for (j = phst[i-1]; j < phst[i]; ++j){ *(ptr = psrt[j]) = MASK; for (k = 0; k < graph; ++k){ if (*(ptr + shift[k]) < MASK){ *ptr = INQUEUE; fifo4_add(q, (long int)ptr); break; } } } ptr = (PIX_TYPE *)fifo4_remove(q); while (ptr){ for (k = 0; k < graph; ++k){ if (*(p = ptr + shift[k]) < WSHED){ if ( (*ptr == INQUEUE) || (*ptr == WSHED && flag == TRUE) ) *ptr = *p; else if ( (*ptr < WSHED) && (*ptr != *p) ){ *ptr = WSHED; flag = FALSE; } } else if (*p == WSHED){ if (*ptr == INQUEUE){ *ptr = WSHED; flag = TRUE; } } else if (*p == MASK){ *p = INQUEUE; fifo4_add(q, (long int)p); } } ptr = (PIX_TYPE *)fifo4_remove(q); } /* check if new minima have been discovered, and label them */ for (j = phst[i-1]; j < phst[i]; ++j){ ptr = psrt[j]; if (*ptr == MASK){ *ptr = lbl; fifo4_add(q, (long int)ptr); while ((ptr = (PIX_TYPE *)fifo4_remove(q))){ for (k = 0; k < graph; ++k){ if (*(p = ptr + shift[k]) == MASK){ *p = lbl; fifo4_add(q, (long int)p); } } } lbl++; if (lbl==WSHED){ /* start again with 0 labels and prey */ (void)sprintf(buf,"WARNING in us_flood1: label overflow starting from 0 again\n"); errputstr(buf); lbl=0; } } } } free_fifo4(q); for (i=0; iJIPlib") (font "Sans") (font-size 18.000000) (font-size-unit pixels) (antialias yes) (language "en-us") (base-direction ltr) (color (color-rgb 1.000000 0.941176 0.000000)) (justify left) (box-mode dynamic) (box-unit pixels) (hinting yes) j &e&q&}jT , !%q                                                                                                                                       $(*,-. / 0000                 0000/ . -,*($..$(*,../ 0000                 0000/ ..,*($..ͶnC$͈1(g*c,"-M.[ / 0000!J I   1  f +    - i  4    I  I0000/ .] -N,"*d(i $Ή3ϸqF..                                                      N,  m  c   R            Q   c  m  , P////////////////// . / 0                 ////////////////// . 00                 //////////////////@޹L - 6!_`o.3 / 0s31kH=   F ?  JE   wv II ''        '' II ---p r? T                     *)(#!"""#$$%&()+ -2                     *)(#!"""#$$%&()+ -2                " B y   Q*C);( v#%Q5!"W""7#y$$%&_()+ ߝO-ҺxM2...................................... ...................         0/ .  .I        00.  .I wu   ID  F <    G;r2/i0/ .5 rbc #1 7.C໏O I&T!@t r5A Layer     '7'W+7+C+O('(7(G(W(g(w(((((((()))')7)G)W)g)w))))))))***'*7*G*W*g*w********+++'dd22text     ,,(/D/P/\,----(-4-@-L-X-d-p-|----------.. ..$.0.<.H.T.`.l.x.........../// /,/8dd22Selection Mask /0 1110000000000111 111111"1&1*1.12161:1>1B1F1J1N1R1V1Z1^1b1f1j1n1r1v1z1~1111111dd22jeolib-miallib-1.1.6/miallib-config.cmake.in000066400000000000000000000010761467232417700206760ustar00rootroot00000000000000set(MIALLIB_VERSION @MIALLIB_VERSION@) @PACKAGE_INIT@ set_and_check(MIALLIB_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@") set_and_check(MIALLIB_INCLUDE_DIRS ${MIALLIB_INCLUDE_DIR}) set_and_check(MIALLIB_LIBRARY_DIR "@PACKAGE_LIBRARY_INSTALL_DIR@") # set_and_check(MIALLIB_LIBRARY "@PACKAGE_LIBRARY_INSTALL_DIR@/libmiallib.so") # set_and_check(MIALLIB_LIBRARIES "@PACKAGE_LIBRARY_INSTALL_DIR@/libmiallib.so") set_and_check(MIALLIB_LIBRARY "@PACKAGE_LIBRARY_INSTALL_DIR@/libmiallib.so") set_and_check(MIALLIB_LIBRARIES ${MIALLIB_LIBRARY}) check_required_components(miallib) jeolib-miallib-1.1.6/swig/000077500000000000000000000000001467232417700153605ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/include/000077500000000000000000000000001467232417700170035ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/include/master.i000066400000000000000000000605561467232417700204640ustar00rootroot00000000000000/* master.i */ %include constraints.i // %feature("docstring"); %define DOCSTRING "Module containing base master image funcionalities. They correspond directly to the MIALib C function wrapped to python thanks to SWIG. This is an initial test module for the JIPL (Joint Image Processing Library) developed in the framework of the JEODPP of the EO&SS@BigData pilot project. Contact: Pierre.Soille@jrc.ec.europa.eu" %enddef %feature("autodoc", "1"); // It consists of wrappers of C code underlying mialisp orginally developed // by Pierre Soille over the years since 1988. %module(docstring=DOCSTRING) master_base // see https://stackoverflow.com/questions/11435102/is-there-a-good-way-to-produce-documentation-for-swig-interfaces %import "../../../core/build/doc/xml/mial_doxy2swig.i" %{ /* Put header files here or function declarations like below */ #include "miallib_swig.h" #include "miallib_master.h" #include "op.h" #include "miallib_imem.h" // for functions called in %extend #define printf PySys_WriteStdout extern void free_image(IMAGE *); %} // See info on cpointers // http://www.swig.org/Doc3.0/SWIGDocumentation.html#Library_nn3 //%include cpointer.i //%pointer_functions(IMAGE,imagep) //%pointer_functions(IMAGE *,imap) // definition of array pointers // for use, e.g., in writing multiband image //NO_NEED_4_POINTOP %include carrays.i //NO_NEED_4_POINTOP %array_functions(IMAGE *, imap) //NO_NEED_4_POINTOP %array_functions(int , intp) // used for example for box array //NO_NEED_4_POINTOP %array_functions(double , doublep) // %nodefaultctor image; // No default constructor // %nodefaultdtor image; // No default destructor // renaming: /* imem.c */ /* %rename(imInfo) iminfo; */ /* %rename(imToArray) imtoarray; */ /* %rename(arrayToIm) arraytoim; */ /* %rename(setPixVal) setpixval; */ /* %rename(getPixVal) getpixval; */ /* %rename(createImArray) create_imarray; */ // rename the C declarations // %rename("%(lowercamelcase)s", %$isfunction) ""; // foo_bar -> fooBar; FooBar -> fooBar // %rename("nd_%s", regextarget=1, fullname=1) "IMAGE \*\(.*"; /* %rename(convolve) convolve; */ /* %rename(convolveDownSample) convolvedownsample; */ /* %rename(runSum2d) rsum2d; */ /* %rename(runSum3d) rsum3d; */ /* %rename(runSumInSquareNgb) rsumsq2d; */ /* %rename(meanInSquareNgb) mean2d; */ /* %rename(meanFilter2d) mean2dse; */ /* %rename(varianceFilter2d) variance2dse; */ /* %rename(gradientAzimuth) azimuth; */ /* %rename(orientationMap) mapori; */ /* %rename(phaseCorrelation) phase_correlation; */ /* %rename(flowDirectionD8) d8; */ /* %rename(flowDirectionDInf) dinf; */ /* %rename(slopeD8) slope8; */ /* %rename(flow) flow; */ /* %rename(flowNew) flownew; */ /* %rename(contributingDrainageArea) cda; */ /* %rename(contributingDrainageAreaStratify) stratify; */ /* %rename(contributingDrainageAreaDInf) cdainf; */ /* %rename(slopeDInf) slopeinf; */ /* %rename(floodDirection) dir; */ /* %rename(catchmentBasinOutlet) cboutlet; */ /* %rename(catchmenBasinConfluence) cbconfluence; */ /* %rename(strahlerOrder) strahler; */ /* %rename(pitRemovalCarve) aflood; */ /* %rename(pitRemovalOptimal) fillocarve; */ /* %rename(flowDirectionFlat) FlatDir; */ /* %rename(flowDirectionFlatGeodesic) FlatIGeodAFAB; */ /* %rename(upstreamMaxHeight) htop; */ /* %rename(shade) shade; */ /* %rename(lineDilate3d) LineDilate3D; */ /* %rename(distance2d4) dst2d4; */ /* %rename(distance2dChamfer57) dst2dchamfer; */ /* %rename(distance2dChamfer) chamfer2d; */ /* %rename(distance2dEuclideanFifo) edistfifo2d; */ /* %rename(distance2dEuclideanSquared) sqedt; */ /* %rename(influenceZones2dEuclidean) iz; */ /* %rename(influenceZones2dOrderedIndependent) oiiz; */ /* %rename(distanceGeodesic) geodist; */ /* %rename(distance2dEuclideanConstrained) ced; */ /* %rename(erodeLine) linero; */ /* %rename(dilateLine) lindil; */ /* %rename(dilateLinePeriodic) herkpldil; */ /* %rename(erodeLinePeriodic) herkplero; */ /* %rename(erodeNgb4) erode4; */ /* %rename(dilateNgb4) dilate4; */ /* %rename(erode) erode; */ /* %rename(dilate) dilate; */ /* %rename(erodeVolumic) volerode; */ /* %rename(rankFilter) rank; */ /* %rename(rankFilterSquare) squarerank; */ /* %rename(sumInSquareNgb) squarevol; */ /* %rename(rankFilterLine) linerank; */ /* %rename(rankFilerLineTI) lrankti; */ /* %rename(erodeLabel) erodelabel; */ /* %rename(gradientMultibandSquareNgb) msgradlinf; */ /* %rename(gradientMultiband) msgradlinfngb; */ /* %rename(to1bitPerPixel) to_tiff1bitpp; */ /* %rename(to4bitPerPixel) to_tiff4bitpp; */ /* %rename(toUint16) to_ushort; */ /* %rename(toUint32) to_int32; */ /* %rename(toFloat32) to_float; */ /* %rename(toDouble64) to_double; */ /* %rename(toUchar8) to_uchar; */ /* %rename(double64ToFloat32) dbltofloat; */ /* %rename(uint32toFloat32) uint32_to_float; */ /* %rename(swapBytes) swap; */ /* %rename(deinterleave) deinterleave; */ /* %rename(hsi2rgb) imhsi2rgb; */ /* %rename(hls2rgb) imhls2rgb; */ /* %rename(rgb2hsx) imrgb2hsx; */ /* %rename(rgbTo3d) crgb2rgb; */ /* %rename(reconstructionByDilation) rdil; */ /* %rename(reconstructionByErosion) rero; */ /* %rename(reconstruction) rerodilp; */ /* %rename(complete) complete; */ /* %rename(minima) minima; */ /* %rename(geodesicTimeFlat) sqtgpla; */ /* %rename(geodesicTime) sqtg; */ /* %rename(geodesicTimeSymetric) sqtgsym; */ /* %rename(frameSet) framebox; */ /* %rename(frameAdd) addframebox; */ /* %rename(frameSubtract) subframebox; */ /* %rename(dumpBox) dumpxyz; */ /* %rename(imageInsert) imputop; */ /* %rename(imageInsertCompose) imputcompose; */ /* %rename(imageCut) imcut; */ /* %rename(getNonZeroBoundingBox) getboundingbox; */ /* %rename(magnify) magnify; */ /* %rename(rotateCoordinates) rotatecoor; */ /* %rename(sizeAndTypeEqualPredicate) szcompat; */ /* %rename(sizeEqualPredicate) szgeocompat; */ /* %rename(plotLine) plotline; */ /* %rename(overlapMatrix) ovlmatrix; */ /* %rename(skeleton) skeleton; */ /* %rename(pruneBinary) bprune; */ /* %rename(extractPixelConfigurationBinary) epc; */ /* %rename(extractPixelConfigurationGrey) epcgrey; */ /* %rename(switchOperator) switchop; */ /* %rename(skeletonOrderIndependent) oiskeleton; */ /* %rename(skeletonAnchored) oiask; */ /* %rename(orderDependentThin) binODthin_noqueue; */ /* %rename(orderDependentThinFifo) binODthin_FIFO; */ /* %rename(orderIndependentThin) binOIthin_noqueue; */ /* %rename(orderIndependentThinFifo) binOIthin_FIFO; */ /* %rename(imageInfo) iminfo; */ /* %rename(imageCreate) create_image; */ /* %rename(imageCopy) copy_image; */ /* %rename(lutCopy) copy_lut; */ /* %rename(lutCreate) create_lut; */ /* %rename(lutFree) free_lut; */ /* %rename(imageToArray) imtoarray; */ /* %rename(imageFromArray) arraytoim; */ /* %rename(setPixVal) setpixval; */ /* %rename(getPixVal) getpixval; */ /* %rename(getPixWithVal) FindPixWithVal; */ /* %rename(getBitsPerPixel) GetImBitPerPixel; */ /* %rename(probalyNotNeededInJIPLib) GDAL2MIALDataType; */ /* %rename(GDALInfo) GDALInfoJIP; */ /* %rename(GDALRead) GDALRead; */ /* %rename(readImageBinary) read_all; */ /* %rename(readImage) read_image; */ /* %rename(readImageToType) read_image_to_type; */ /* %rename(writeColorMapTiff) write_ColorMap_tiff; */ /* %rename(writeTiff) write_tiff; */ /* %rename(writeTiffOneStripPerLine) writeTiffOneStripPerLine; */ /* %rename(GDALGetGeoKey) GetGeoKey; */ /* %rename(GDALGetTiffTagGeo) GetTIFFTagGeo; */ /* %rename(readImageScale) read_image2; */ /* %rename(readTiffSubset) readTiffSubset; */ /* %rename(TiffInfoFieldValue) tiffinfo; */ /* %rename(TiffInfo) tiffinfoJIP; */ /* %rename(writeGeoTiff) writeGeoTiffOneStripPerLine; */ /* %rename(writeMultibandGeoTiff) writeMBGeoTiffOneStripPerLine; */ /* %rename(labelBinary) label; */ /* %rename(labelFlatZones) labelplat; */ /* %rename(labelFlatZonesSeeded) seededlabelplat; */ /* %rename(flatZonesSeeded) seededplat; */ /* %rename(labelPix) labelpix; */ /* %rename(labelsResolve) resolveLabels; */ /* %rename(labelsReorder) gorder; */ /* %rename(propagate) propagate; */ /* %rename(labelsSet) set_regions; */ /* %rename(labelsSetGraph) setregionsgraph; */ /* %rename(labelsSetArea) tessel_surface; */ /* %rename(labelRelabel) relabel; */ /* %rename(labelsGetLut) region_lut; */ /* %rename(labelsGetLutSeq) region_lut_seq; */ /* %rename(labelsImageGetLut) region_im_lut; */ /* %rename(labelsGetContortionLut) contortion_lut; */ /* %rename(momentsLutsToEllipseLuts) moments_lut_to_ellipse_lut; */ /* %rename(dissimToAlphaCCs) alphacc; */ /* %rename(vertexDegreeAlpha) labelvertex; */ /* %rename(vertexSeparation) vertexseparation; */ /* %rename(labelVertexConnectedness) labelvertexconnectedness; */ /* %rename(labelAlphaCCs) labelcc; */ /* %rename(labelConstrainedCCsMultiband) labelccms; */ /* %rename(labelStronglyCCs) labelci; */ /* %rename(labelStronglyCCsMultiband) labelcims; */ /* %rename(labelConstrainedCCs) labelccdissim; */ /* %rename(labelConstrainedCCsVariance) labelccvar; */ /* %rename(labelConstrainedCCsMultibandDissim) labelccmsdissim; */ /* %rename(labelConstrainedCCsAttr) labelccattr; */ /* %rename(alphaTreeDissimGet) alphatree; */ /* %rename(alphaTree) alphatreeincattr; */ /* %rename(alphaTreeToCCs) alphatreetoCCs; */ /* %rename(alphaTreeNextLevel) alphatreenextlevel; */ /* %rename(alphaTreeGetPersistenceLut) alphatreepersistencelut; */ /* %rename(edgeWeight) edgeweight; */ /* %rename(dissim) dissim; */ /* %rename(dbscan) dbscan; */ /* %rename(labelsGetOuterEdgeLut) outeredgelut; */ /* %rename(labelsGetOuterEdge) outeredge; */ /* %rename(labelsGetOuterContour) outercontour; */ /* %rename(orientationMean) dirmean; */ /* %rename(orientationCoherence) coherence; */ /* %rename(paraboloidGetCoordinatesExtremum) coor_extrema_paraboloid; */ /* %rename(linearFitGSL) fitlinear; */ /* %rename(gradientTransition) transgrad; */ /* %rename(julianDate) julian_date; */ /* %rename(openingAttribute) attribute; */ /* %rename(openingArea) GreyAreaOpening; */ /* %rename(closingArea) GreyAreaClosing; */ /* %rename(openingAreaROI) GreyAreaOpeningROI; */ /* %rename(closingAreaROI) GreyAreaClosingROI; */ /* %rename(convexHull) chull; */ /* %rename(closingHalfplane) hpclose; */ /* %rename(closingHalfplaneTI) hpcloseti; */ /* %rename(pointOpBitwise) bitwise_op; */ /* %rename(pointOpNegation) negation; */ /* %rename(pointOpArith) arith; */ /* %rename(pointOpArithCst) arithcst; */ /* %rename(pointOpAbs) imabs; */ /* %rename(pointOpSqrt) imsqrt; */ /* %rename(pointOpLog) imlog; */ /* %rename(pointOpAtan) imatan; */ /* %rename(pointOpCos) imcos; */ /* %rename(pointOpAcos) imacos; */ /* %rename(pointOpSin) imsin; */ /* %rename(pointOpAsin) imasin; */ /* %rename(pointOpThresh) thresh; */ /* %rename(pointOpSetLevel) setlevel; */ /* %rename(pointOpModulo) modulo; */ /* %rename(pointOpComplement) complement; */ /* %rename(pointOpPower2) power2p; */ /* %rename(pointOpBlank) blank; */ /* %rename(pointOpBitShift) shift; */ /* %rename(pointOpSetRange) setrange; */ /* %rename(gridding) grid; */ /* %rename(cs2cs) cs2cs; */ /* %rename(watershed) ws; */ /* %rename(watershedFAH) wsfah; */ /* %rename(skeletonFah) skelfah; */ /* %rename(skeletonFah2) skelfah2; */ /* %rename(compose) compose; */ /* %rename(watershedOrderIndependent) oiws; */ /* %rename(seededRegionGrowing) srg; */ /* %rename(seededRegionGrowingMultiband) mssrg; */ /* %rename(seededRegionGrowingCore) mssrgcore; */ /* %rename(labelQuasiFlatZones) labelImage; */ /* %rename(seededRegionGrowingMultiband) mcisrg; */ /* %rename(segmentImageMultiband) segmentImage; */ /* %rename(writeGnuPlot3D) writeGnuPlot3D; */ /* %rename(vectorizeImage) vectorizeImage; */ /* %rename(partitionEqualPredicate) IsPartitionEqual; */ /* %rename(partitionFinerPredicate) IsPartitionFiner; */ /* %rename(imgc) imgc; */ /* %rename(dendrogram) dendro; */ /* %rename(partitionSimilarity) PartitionSimilarity; */ /* %rename(histo1d) histo1d; */ /* %rename(histo2d) histo2d; */ /* %rename(histo3d) histo3d; */ /* %rename(histo1dCumulative) rsum; */ /* %rename(lookupRgb) lookuprgb; */ /* %rename(class2d) class2d; */ /* %rename(surfaceArea) area; */ /* %rename(runSumDir) dirsum; */ /* %rename(getMinMax) min_max; */ /* %rename(getFirstMaxOffset) getfirstmaxpos; */ /* %rename(histoCompress) histcompress; */ /* %rename(lookup) lookup; */ /* %rename(lookupTypeMatch) lookuptypematch; */ /* %rename(volume) volume; */ /* %rename(propagateMaxDir) dirmax; */ /* %rename(equalityPredicate) imequalp; */ /* %rename(getMax) getmax; */ /* %rename(getMinMax) getminmax; */ /* %rename(histoMatchRgb) histrgbmatch; */ /* %rename(histoMatch3dRgb) histrgb3dmatch; */ /* %rename(linearCombinationMultiband) mblincomb; */ /* %rename(meanConditional) condmean; */ /* %rename(sortIndex) sortindex; */ /* %rename(classStatsInfo) classstatsinfo; */ /* %rename(classMinDst) clmindist; */ /* %rename(classBox) clparpip; */ /* %rename(classMahanalobis) clmaha; */ /* %rename(classMaximumLikelihood) clmaxlike; */ /* %rename(similarityDetectionSequential) ssda; */ /* %rename(crosscorrNormalisedLewis) ncclewis; */ /* %rename(crosscorrNormalised) ncc; */ // new object with their constructor and destructor //%newobject *IMAGE(); //%newobject *G_TYPE(); //%typemap(newfree) IMAGE * "free_image($1);"; // 20160922 // define each miallib function returning a new IMAGE as a new object // this triggers the setting of 'SWIG_POINTER_OWN' for the new IMAGE // rather than '0' previously // (note that for the destructor ~IMAGE() the setting is 'SWIG_POINTER_NEW') %include miallib_newobjects.i /* %typemap(in, numinputs=0) double * (double temp){ */ /* printf("typemap(in)\n"); */ /* temp=99.0; */ /* $1 = &temp; */ /* printf("%g %g\n", temp, *arg2); */ /* } */ %typemap(out) ERROR_TYPE getminmax { if (result!=NO_ERROR){ PyErr_SetString(PyExc_ValueError,"getmimax() returned error"); return NULL; } $result = PyList_New(2); } %typemap(argout) double * { PyObject * o = 0 ; double temp$argnum; printf("typemap(argout); %d val=%g\n", $argnum, temp$argnum); o=PyFloat_FromDouble(temp$argnum); PyList_SetItem($result,($argnum)-2,o); } %typemap(out) G_TYPE *min_max { PyObject * o = 0 ; double min, max; if (result==NULL){ PyErr_SetString(PyExc_ValueError,"min_max() returned error"); return NULL; } $result = PyList_New(2); if (arg1!=NULL){ switch (GetImDataType(arg1)){ case t_UCHAR: min=result[0].uc_val; max=result[1].uc_val; break; case t_USHORT: min=result[0].us_val; max=result[1].us_val; break; case t_SHORT: min=result[0].s_val; max=result[1].s_val; break; case t_UINT32: min=result[0].u32_val; max=result[1].u32_val; break; case t_INT32: min=result[0].i32_val; max=result[1].i32_val; break; case t_UINT64: min=result[0].u64_val; max=result[1].u64_val; break; case t_INT64: min=result[0].i64_val; max=result[1].i64_val; break; case t_FLOAT: min=result[0].f_val; max=result[1].f_val; break; case t_DOUBLE: min=result[0].d_val; max=result[1].d_val; break; default: PyErr_SetString(PyExc_ValueError,"min_max() invalid data type"); return NULL; } o=PyFloat_FromDouble(min); PyList_SetItem($result,0,o); o=PyFloat_FromDouble(max); PyList_SetItem($result,1,o); } else return NULL; } // typemaps for: // extern ERROR_TYPE FindPixWithVal(IMAGE *im, G_TYPE gval, unsigned long int *ofs); %typemap(check) unsigned long int ofs { if ($1 < 0) { SWIG_exception(SWIG_ValueError, "Expected non-negative value."); } } %typemap(in, numinputs=0) unsigned long int *ofs (unsigned long int temp) { $1 = &temp; } %typemap(argout) unsigned long int *ofs { PyObject * o = 0 ; printf("typemap(argout); %d val=%g\n", $argnum, temp$argnum); o=PyLong_FromLong(temp$argnum); $result = o; } // handle G_TYPE arguments as Python Float value in python %typemap(in) G_TYPE { G_TYPE gt; if (!PyFloat_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a number"); return NULL; } double dval=PyFloat_AsDouble($input); gt.generic_val=(unsigned char)dval; gt.uc_val=(unsigned char)dval; gt.us_val=(unsigned short)dval; gt.s_val=(short)dval; gt.i32_val=(int)dval; gt.u32_val=(unsigned int)dval; gt.i64_val=(long int)dval; gt.u64_val=(unsigned long int)dval; gt.f_val=(float)dval; gt.d_val=(double)dval; $1=gt; } %typemap(out) G_TYPE getpixval { double dval=0.0; switch (GetImDataType(arg1)) { case t_UCHAR: dval=(double)$1.uc_val; break; case t_SHORT: dval=(double)$1.s_val; break; case t_USHORT: dval=(double)$1.us_val; break; case t_INT32: dval=(double)$1.i32_val; break; case t_UINT32: dval=(double)$1.u32_val; break; case t_INT64: dval=(double)$1.i64_val; break; case t_UINT64: dval=(double)$1.u64_val; break; case t_MIALFLOAT: dval=(double)$1.f_val; break; case t_DOUBLE: dval=(double)$1.d_val; break; default: printf("getpixval(): undefined pixel type (%d) !\n)", GetImDataType(arg1)); } $result=PyFloat_FromDouble(dval); } // 20160923 // define a typemap to handle IMAGE arrays as lists in Python // needed to specify names to have multiple argument working %typemap(in) (IMAGE **imap, int nc) { int i,dim; int res1; void *argp1 = 0 ; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } dim=PySequence_Length($input); $2=dim; printf("message: dim=%d\n", dim); $1 = (IMAGE **) malloc(dim*sizeof(IMAGE **)); for (i = 0; i < dim; i++) { PyObject *o = PySequence_GetItem($input,i); res1 = SWIG_ConvertPtr(o, &argp1,SWIGTYPE_p_IMAGE, 0 | 0 ); if (SWIG_IsOK(res1)) { $1[i] = (IMAGE *) argp1; } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be IMAGE pointers"); free($1); return NULL; } } } // Free the image array %typemap(freearg) (IMAGE **imap) { free($1); } // typemaps for: // IMAGE **cs2cs(double ulc_e, double ulc_n, int nx, int ny, double res, char *parmsi[], int ni, char *parmso[], int no); // Python String Functions http://swig.org/Doc3.0/SWIGDocumentation.html#Python_nn49 // PyObject *PyString_FromString(char *); // PyObject *PyString_FromStringAndSize(char *, lint len); // int PyString_Size(PyObject *); // char *PyString_AsString(PyObject *); // int PyString_Check(PyObject *); %typemap(in) (char *parmsi[], int ni) { int i, dim; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } dim=PySequence_Length($input); printf("message: dim=%d\n", dim); $1 = (char **) calloc(dim,sizeof(char *)); $2=dim; for (i = 0; i < dim; i++) { PyObject *o = PySequence_GetItem($input,i); if (PyString_Check(o)) { $1[i] = (char *)PyString_AsString(o); printf("para: %s\n", $1[i]); } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be strings"); free($1); return NULL; } } } // Free parmsi array %typemap(freearg) (char *parmsi[]) { free($1); } %typemap(in) (char *parmso[], int no) { int i, dim; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } dim=PySequence_Length($input); printf("message: dim=%d\n", dim); $1 = (char **) calloc(dim,sizeof(char *)); $2=dim; for (i = 0; i < dim; i++) { PyObject *o = PySequence_GetItem($input,i); if (PyString_Check(o)) { $1[i] = (char *)PyString_AsString(o); } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be strings"); free($1); return NULL; } } } // Free parmso array %typemap(freearg) (char *parmso[]) { free($1); } // 20170317 // integer array with 2,4, or 6 size parameters (1-D, 2-D, or 3-D images respectively) %typemap(in) (int *box) { int i, dim; $1 = (int *) calloc(6, sizeof(int)); if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } dim=PySequence_Length($input); if ((dim!=2) || (dim!=4) || (dim!=6)){ for (i = 0; i < dim; i++) { PyObject *o = PySequence_GetItem($input,i); // https://docs.python.org/3.5/c-api/long.html if (PyInt_Check(o)) { $1[i] = (int)PyInt_AsLong(o); } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be integers"); free($1); return NULL; } } } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be equal to 2, 4, or 6 for the size of the [left, right], [left, right, top, bottom], or [left, right, top, bottom, up, down] borders respectively."); return NULL; } } // Free the box array %typemap(freearg) (int *box) { free($1); } %typemap(check) int *box { int i; for (i=0; i<6; i++){ if ($1[i] < 0) { SWIG_exception(SWIG_ValueError, "Expected non-negative value."); } } } // // handling IMAGE array output argument as python list // %typemap(out) IMAGE **cs2cs { int i; int nc=2; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **rotatecoor { int i; int nc=2; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **imrgb2hsx { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **PartitionSimilarity { int i; int nc=4; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **alphatree { int i; int nc=5; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **histrgbmatch { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **histrgb3dmatch { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **imgc { int i; int nc=2; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } /* %typemap(argout) ERROR_TYPE to_uchar(IMAGE *) { */ /* PyObject * o = 0 ; */ /* printf("message: typemap(argout) test\n"); */ /* Py_XDECREF($result); /\* Blow away any previous result *\/ */ /* if (result > 0) { /\* Check for I/O error *\/ */ /* PyErr_SetFromErrno(PyExc_IOError); */ /* return NULL; */ /* } */ /* o = SWIG_NewPointerObj(SWIG_as_voidptr(im), 0 | 0 ); */ /* $result = o; */ /* } */ // These are the headers with the declarations that will be warped // It needs to be inserted before the extend declaration //%include "miallib_swig.h" //%include "op.h" %include "mialtypes.h" // this is needed to secure garbage collection ! %include "miallib_master.h" // 20160922 // Allow for automatic garbage collection (no need to patch!) %extend IMAGE { // Attach these functions to struct IMAGE IMAGE(int type, long int nx, int ny, int nz) { return create_image(type, nx,ny,nz); } ~IMAGE() { free_image($self); } void iminfoMethod() { iminfo($self); } }; %typemap(newfree) IMAGE * { delete $1; } // Addtional code for IMAGE<->NumPy array conversions [20160729] // adapted from gdal_array.i %init %{ // import_array(); %} #if defined(SWIGPYTHON) //%include "miallib_python.i" #endif jeolib-miallib-1.1.6/swig/include/miallib.i000066400000000000000000000200341467232417700205650ustar00rootroot00000000000000/* miallib.i */ %include constraints.i // %feature("docstring"); %define DOCSTRING "This is an initial test module for the JIPL (Joint Image Processing Library) developed in the framework of the JEODPP of the EO&SS@BD pilot project. Emphasis is on morphological image analysis functionalities. Contact: Pierre.Soille@jrc.ec.europa.eu" %enddef %feature("autodoc", "1"); // It consists of wrappers of C code underlying mialisp orginally developed // by Pierre Soille over the years since 1988. %module(docstring=DOCSTRING) miallib // see https://stackoverflow.com/questions/11435102/is-there-a-good-way-to-produce-documentation-for-swig-interfaces %import "mial_doxy2swig.i" %{ /* Put header files here or function declarations like below */ #include "miallib_swig.h" #include "op.h" %} // See info on cpointers // http://www.swig.org/Doc3.0/SWIGDocumentation.html#Library_nn3 //%include cpointer.i //%pointer_functions(IMAGE,imagep) //%pointer_functions(IMAGE *,imap) // definition of array pointers // for use, e.g., in writing multiband image %include carrays.i %array_functions(IMAGE *, imap) %array_functions(int , intp) // used for example for box array %array_functions(double , doublep) // %nodefaultctor image; // No default constructor // %nodefaultdtor image; // No default destructor // renaming: /* imem.c */ /* %rename(imInfo) iminfo; */ /* %rename(imToArray) imtoarray; */ /* %rename(arrayToIm) arraytoim; */ /* %rename(setPixVal) setpixval; */ /* %rename(getPixVal) getpixval; */ /* %rename(createImArray) create_imarray; */ // rename the C declarations // %rename("%(lowercamelcase)s", %$isfunction) ""; // foo_bar -> fooBar; FooBar -> fooBar // %rename("nd_%s", regextarget=1, fullname=1) "IMAGE \*\(.*"; // new object with their constructor and destructor //%newobject *IMAGE(); //%newobject *G_TYPE(); //%typemap(newfree) IMAGE * "free_image($1);"; // 20160922 // define each miallib function returning a new IMAGE as a new object // this triggers the setting of 'SWIG_POINTER_OWN' for the new IMAGE // rather than '0' previously // (note that for the destructor ~IMAGE() the setting is 'SWIG_POINTER_NEW') %include miallib_newobjects.i %typemap(in, numinputs=0) double * (double temp){ printf("typemap(in)\n"); temp=99.0; $1 = &temp; printf("%g %g\n", temp, *arg2); } %typemap(out) ERROR_TYPE getminmax { if (result!=NO_ERROR){ PyErr_SetString(PyExc_ValueError,"getmimax() returned error"); return NULL; } $result = PyList_New(2); } %typemap(argout) double * { PyObject * o = 0 ; printf("typemap(argout); %d val=%g\n", $argnum, temp$argnum); o=PyFloat_FromDouble(temp$argnum); PyList_SetItem($result,($argnum)-2,o); } // handle G_TYPE arguments as Python Float value in python %typemap(in) G_TYPE { G_TYPE gt; // printf("coucou\n"); if (!PyFloat_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a number"); return NULL; } double dval=PyFloat_AsDouble($input); gt.generic_val=(unsigned char)dval; gt.uc_val=(unsigned char)dval; gt.us_val=(unsigned short)dval; gt.s_val=(short)dval; gt.i32_val=(int)dval; gt.u32_val=(unsigned int)dval; gt.i64_val=(long int)dval; gt.u64_val=(unsigned long int)dval; gt.f_val=(float)dval; gt.d_val=(double)dval; $1=gt; } %typemap(out) G_TYPE getpixval { double dval=0.0; switch (GetImDataType(arg1)) { case t_UCHAR: dval=(double)$1.uc_val; break; case t_SHORT: dval=(double)$1.s_val; break; case t_USHORT: dval=(double)$1.us_val; break; case t_INT32: dval=(double)$1.i32_val; break; case t_UINT32: dval=(double)$1.u32_val; break; case t_INT64: dval=(double)$1.i64_val; break; case t_UINT64: dval=(double)$1.u64_val; break; case t_MIALFLOAT: dval=(double)$1.f_val; break; case t_DOUBLE: dval=(double)$1.d_val; break; } $result=PyFloat_FromDouble(dval); } // 20160923 // define a typemap to handle IMAGE arrays as lists in Python // needed to specify names to have multiple argument working %typemap(in) (IMAGE **imap, int nc) { int i,dim; int res1; void *argp1 = 0 ; if (!PySequence_Check($input)) { PyErr_SetString(PyExc_ValueError,"Expected a sequence"); return NULL; } dim=PySequence_Length($input); $2=dim; printf("message: dim=%d\n", dim); $1 = (IMAGE **) malloc(dim*sizeof(IMAGE **)); for (i = 0; i < dim; i++) { PyObject *o = PySequence_GetItem($input,i); res1 = SWIG_ConvertPtr(o, &argp1,SWIGTYPE_p_IMAGE, 0 | 0 ); if (SWIG_IsOK(res1)) { $1[i] = (IMAGE *) argp1; } else { PyErr_SetString(PyExc_ValueError,"Sequence elements must be IMAGE pointers"); free($1); return NULL; } } } // handling IMAGE array output argument as python list %typemap(out) IMAGE **rotatecoor { int i; int nc=2; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **imrgb2hsx { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **PartitionSimilarity { int i; int nc=4; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **alphatree { int i; int nc=5; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **histrgbmatch { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **histrgb3dmatch { int i; int nc=3; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } %typemap(out) IMAGE **imgc { int i; int nc=2; IMAGE **imap=(IMAGE **)$1; $result = PyList_New(nc); PyObject * o = 0 ; for (i = 0; i < nc; i++) { o = SWIG_NewPointerObj(SWIG_as_voidptr(imap[i]), SWIGTYPE_p_IMAGE, SWIG_POINTER_OWN | 0 ); PyList_SetItem($result,i,o); } free(imap); } /* %typemap(argout) ERROR_TYPE to_uchar(IMAGE *) { */ /* PyObject * o = 0 ; */ /* printf("message: typemap(argout) test\n"); */ /* Py_XDECREF($result); /\* Blow away any previous result *\/ */ /* if (result > 0) { /\* Check for I/O error *\/ */ /* PyErr_SetFromErrno(PyExc_IOError); */ /* return NULL; */ /* } */ /* o = SWIG_NewPointerObj(SWIG_as_voidptr(im), 0 | 0 ); */ /* $result = o; */ /* } */ // These are the headers with the declarations that will be warped // It needs to be inserted before the extend declaration %include "miallib_swig.h" %include "op.h" // 20160922 // Allow for automatic garbage collection (no need to patch!) %extend IMAGE { // Attach these functions to struct IMAGE IMAGE(int type, long int nx, int ny, int nz) { return create_image(type, nx,ny,nz); } ~IMAGE() { free_image($self); } void iminfoMethod() { iminfo($self); } }; %typemap(newfree) IMAGE * { delete $1; } // Addtional code for IMAGE<->NumPy array conversions [20160729] // adapted from gdal_array.i %init %{ print_mia_banner(); import_array(); %} #if defined(SWIGPYTHON) %include miallib_python.i #endif jeolib-miallib-1.1.6/swig/include/python/000077500000000000000000000000001467232417700203245ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/include/python/miallib_python.i000066400000000000000000000101161467232417700235070ustar00rootroot00000000000000// python specific interface file // provide support for numpy array with mial %inline %{ //#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include "Python.h" #include "numpy/arrayobject.h" %} %typemap(in,numinputs=1) (PyArrayObject *psArray) { /* %typemap(in,numinputs=1) (PyArrayObject *psArray) */ if ($input != NULL && PyArray_Check($input)) { $1 = (PyArrayObject*)($input); } else { PyErr_SetString(PyExc_TypeError, "not a numpy array"); SWIG_fail; } } %inline %{ void RasterIOMIALib( IMAGE* im, PyArrayObject *psArray) { psArray->data = memcpy((void *)(psArray->data), (void *)GetImPtr(im), GetImNx(im)*GetImNy(im)*GetImNz(im)*(GetImBitPerPixel(im)/8) ); // return NO_ERROR; } void CConvertNumPyArrayToMIALibIMAGE( IMAGE *im, PyArrayObject *psArray) { im->p_im=memcpy( (void *)GetImPtr(im), (void *)(psArray->data), GetImNx(im)*GetImNy(im)*GetImNz(im)*(GetImBitPerPixel(im)/8)); // return NO_ERROR; } %} %pythoncode %{ import numpy from . import imem_base t_UCHAR = 3 t_SHORT = 4 t_USHORT = 5 t_INT32 = 6 t_UINT32 = 7 t_INT64 = 8 t_UINT64 = 9 t_FLOAT = 10 t_MIALFLOAT = 10 t_DOUBLE = 11 def NumPyToImDataTypeCode(numeric_type): """Converts a given numpy array data type code into the correspondent MIALib image data type code.""" if not isinstance(numeric_type, (numpy.dtype,type)): raise TypeError("Input must be a valid numpy Array data type") if numeric_type == numpy.uint8: return t_UCHAR elif numeric_type == numpy.uint16: return t_USHORT elif numeric_type == numpy.int16: return t_SHORT elif numeric_type == numpy.uint32: return t_UINT32 elif numeric_type == numpy.int32: return t_INT32 elif numeric_type == numpy.uint64: return t_UINT64 elif numeric_type == numpy.int64: return t_INT64 elif numeric_type == numpy.float32: return t_FLOAT elif numeric_type == numpy.float64: return t_DOUBLE else: raise TypeError("provided numeric_type not compatible with available IMAGE data types") def ImDataToNumPyTypeCode(ImDataType): """Returns the numpy Array data type code matching a given an MIALib image data type.""" if not isinstance(ImDataType, int): raise TypeError("Input must be an integer value") if ImDataType == t_UCHAR: return numpy.uint8 elif ImDataType == t_USHORT: return numpy.uint16 elif ImDataType == t_SHORT: return numpy.int16 elif ImDataType == t_UINT32: return numpy.uint32 elif ImDataType == t_INT32: return numpy.int32 elif ImDataType == t_UINT64: return numpy.uint64 elif ImDataType == t_INT64: return numpy.int64 elif ImDataType == t_FLOAT: return numpy.float32 elif ImDataType == t_DOUBLE: return numpy.float64 else: return None def ConvertToNumPyArray( im ): """Pure python implementation of converting a MIALib image into a numpy array. Data values are copied!""" buf_obj = numpy.empty([im.ny,im.nx,im.nz], dtype = ImDataToNumPyTypeCode(im.DataType)) if RasterIOMIALib(im, buf_obj) != NO_ERROR: return buf_obj return buf_obj def ConvertNumPyArrayToMIALibImage( psArray ): """Pure python implementation of converting a numpy array into a MIALib image. Data values are copied!""" # im=create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],1) #im=_miallib.create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],1) # with import imem_base #im=create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],1) #im=miallib.create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],1) #im=_imem_base.create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],1) im=imem_base.create_image(NumPyToImDataTypeCode(psArray.dtype),psArray.shape[0],psArray.shape[1],psarray.shape[2]) if CConvertNumPyArrayToMIALibIMAGE(im, psArray) != NO_ERROR: return im return im %} jeolib-miallib-1.1.6/swig/python/000077500000000000000000000000001467232417700167015ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/python/Makefile000066400000000000000000000160741467232417700203510ustar00rootroot00000000000000# Makefile adapted by Pierre.Soille@.ec.europa.eu # for testing jipl C library binding to python # 20160419: added automatic documentation generation using epydoc # 20160928: started to use distutils # ------------------------------------------------------------ # SWIG Examples Makefile # http://crosswire.org/svn/sword/trunk/bindings/swig/oldmake/Makefile.swig # [accessed on 20160127] # # This file is used by the examples to build modules. Assuming # you ran configure, this file will probably work. However, # it's not perfect so you might need to do some hand tweaking. # # Other notes: # # 1. Take a look at the prefixes below. Since SWIG works with # multiple target languages, you may need to find out where # certain packages have been installed. Set the prefixes # accordingly. # # 2. To use this makefile, simply set SRCS, INTERFACE, INCLUDE, LIBS, # TARGET, and do a # $(MAKE) -f Makefile.template.in SRCS='$(SRCS)' \ # INCLUDE='$(INCLUDE) LIBS='$(LIBS)' INTERFACE='$(INTERFACE)' \ # TARGET='$(TARGET)' method # # 'method' describes what is being built. #--------------------------------------------------------------- TARGET = miallib ifndef PYTHON PYTHON=python endif BINDING = python python_version_full := $(wordlist 2,4,$(subst ., ,$(shell python3 --version 2>&1))) python_version_major := $(word 1,${python_version_full}) python_version_minor := $(word 2,${python_version_full}) python_version_patch := $(word 3,${python_version_full}) PYVER=${python_version_major}.${python_version_minor} PYVERSHORT = ${python_version_major} #GDAL include ../SWIGmake.base WRAPPER = $(TARGET)_wrap.c PACKAGE_DIR = ./packages SWIGOUTPUTDIR = extensions MIALLIB_ROOT = ../../core/c/ #BUILDDIR = ../build/python/ BUILDDIR = ./build/ PREFIX=/usr/local INSTALLDOCDIR=${PREFIX}/share/doc/miallib/python/ CC = gcc CXX = c++ prefix = /usr/local exec_prefix= ${prefix} # skipped -DNNI SWIGARGS = -Wall -I../include -I../include/$(BINDING) SWIGDEFINES = -DCLASSIF -DODOITHIN -DMCISRG CFLAGS = -fPIC -DDEBUG -DPYTHON -DOPENMP -DLIIAR -DLIBPROJ -DTESTING -DTEST2 -DEERIE -DUNIX -DCLASSIF -DODOITHIN -DMCISRG -std=c99 -m64 -O3 -Wall -fopenmp -c -Wno-unknown-pragmas INCLUDE = -I./ -I$(MIALLIB_ROOT) -I/usr/local/lib/python${PYVER}/dist-packages/numpy/core/include -I/usr/local/lib/python${PYVER} LIBS = -lgdal -ltiff -lshp -ldl ../../core/build/lib/lib$(TARGET)_python.so LIBDIR = ../../core/build/lib/ INTERFACE = $(TARGET).i SWIGOPT = SWIG = swig RUNTIMEDIR = $(exec_prefix)/lib LIBM = -lieee -lm LIBC = LIBCRYPT = -lcrypt SYSLIBS = $(LIBM) $(LIBC) $(LIBCRYPT) libtool_comp = $(TOP)/../Tools/libtool --mode compile libtool_link = $(TOP)/../Tools/libtool --mode link # X11 options XLIB = -L/usr/X11R6/lib -lX11 XINCLUDE = -I/usr/X11R6/include IWRAP = $(INTERFACE:.i=_wrap.i) ISRCS = $(IWRAP:%.i=$(SWIGOUTPUTDIR)/%.c) ICXXSRCS = $(IWRAP:.i=.cxx) IOBJS = $(IWRAP:%.i=$(BUILDDIR)/temp/$(SWIGOUTPUTDIR)/%.o) # Symbols used for using shared libraries SO= .so LDSHARED= gcc -shared CCSHARED= -fpic CXXSHARED= gcc -shared ################################################################## ##### PYTHON ###### ################################################################## # Make sure these locate your Python installation PYTHON_INCLUDE= -DHAVE_CONFIG_H -I/usr/include/python${PYVER} PYTHON_LIB = # PYTHON_PACKAGES_DIR = /home/soillpi/.local/lib/python${PYVER}/site-packages/ PYTHON_PACKAGES_DIR = /usr/local/lib/python${PYVER}/dist-packages/$(TARGET)/ # Extra Python specific dynamic linking options PYTHON_DLNK = # ---------------------------------------------------------------- # Build a C dynamically loadable module # ---------------------------------------------------------------- #$(LIBDIR)/libjip_python.so: # cd ../ljip/src && make $@ build: ../include/$(TARGET).i ../include/$(BINDING)/$(TARGET)_$(BINDING).i ./setup.py $(MIALLIB_ROOT)/$(TARGET)_swig.h echo $(PYVERSHORT) cat $(MIALLIB_ROOT)/$(TARGET)_*.h | grep '^extern IMAGE \*[a-zA-Z]' | sed 's/extern IMAGE \*/%newobject /' | sed 's/(.*/\;/' | uniq > ../include/$(BINDING)/$(TARGET)_newobjects.i python${PYVERSHORT} setup.py build mv packages/$(TARGET)/$(TARGET).py build/lib.linux-x86_64-${PYVER}/$(TARGET)/ mv packages/$(TARGET)/*_base.py build/lib.linux-x86_64-${PYVER}/$(TARGET)/ python${PYVERSHORT} setup.py bdist $(BUILDDIR)/doc/$(TARGET)_docs_html/toc.html: @mkdir -p $(@D) && if [ ${PYVERSHORT} -eq 2 ]; then export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):../../core/build/lib/ && epydoc -v --name $(TARGET) --html --graph all $(BUILDDIR)/lib.linux-x86_64-${PYVER}/$(TARGET)/ -o $(BUILDDIR)/doc/$(TARGET)_docs_html; fi if [ ${PYVERSHORT} -eq 2 ]; then echo "[Warning:] This makefile can only create the doc for python2.7 using epydoc. For python3.6, use makefile in doc subfolder (doc will be created using sphinx)."; fi $(BUILDDIR)/doc/$(TARGET)_docs_tex/api.tex: @mkdir -p $(@D) && if [ ${PYVERSHORT} -eq 2 ]; then export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:../../core/build/lib/ && epydoc -v --name $(TARGET) --pdf --graph all $(BUILDDIR)/lib.linux-x86_64-${PYVER}/$(TARGET)/ -o $(BUILDDIR)/doc/$(TARGET)_docs_tex; fi if [ ${PYVERSHORT} -eq 2 ]; then echo "[Warning:] This makefile can only create the doc for python2.7 using epydoc. For python3.6, use makefile in doc subfolder (doc will be created using sphinx)."; fi doc: $(BUILDDIR)/doc/$(TARGET)_docs_html/toc.html $(BUILDDIR)/doc/$(TARGET)_docs_tex/api.tex all: build doc install: python${PYVERSHORT} setup.py install --record $(BUILDDIR)/installed_files.txt mkdir -p ${INSTALLDOCDIR}/pdf -find ./build/doc/miallib_docs_tex/ -name api.pdf && cp -a ./build/doc/miallib_docs_tex/api.pdf ${INSTALLDOCDIR}/pdf/ uninstall: cat $(BUILDDIR)/installed_files.txt | xargs rm -f -rm -rf /usr/local/lib/python${PYVER}/dist-packages/miallib -rm -rf ${INSTALLDOCDIR}/pdf/ clean: if [ x$(SWIGOUTPUTDIR) != 'x' ] && [ -d $(SWIGOUTPUTDIR) ]; then rm -rf ${SWIGOUTPUTDIR}; fi if [ x$(BUILDDIR) != 'x' ] && [ -d $(BUILDDIR) ]; then rm -rf ${BUILDDIR}; fi -rm -f ../include/$(BINDING)/$(TARGET)_newobjects.i -rm -f *.pyc -rm -rf *.egg-info -rm -f *.so ./osgeo/*.so -rm -rf dist -rm -f *_wrap.c -rm -f packages/*.py -rm -f packages/$(TARGET).py -rm -f packages/$(TARGET)/$(TARGET).py -rm -f packages/$(TARGET)/*.pyc -rm -f packages/$(TARGET)/_$(TARGET).so -rm -f packages/miallib/*_base.py -find . -name "*pyc" -delete -rm -f ../include/geometry.i -rm -f ../include/imem.i -rm -f ../include/io.i -rm -f ../include/pointop.i -rm -f ../include/convolve.i -rm -f ../include/dem.i -rm -f ../include/dist.i -rm -f ../include/erodil.i -rm -f ../include/format.i -rm -f ../include/geodesy.i -rm -f ../include/hmt.i -rm -f ../include/imstat.i -rm -f ../include/label.i -rm -f ../include/opclo.i -rm -f ../include/proj.i -rm -f ../include/segment.i -rm -f ../include/stats.i veryclean: clean -rm -f ${WRAPPER} if [ x$(SWIGOUTPUTDIR) != 'x' ] && [ -d $(SWIGOUTPUTDIR) ]; then rm -rf ${SWIGOUTPUTDIR}; fi jeolib-miallib-1.1.6/swig/python/doc/000077500000000000000000000000001467232417700174465ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/python/doc/Makefile000077500000000000000000000011361467232417700211120ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build SPHINXPROJ = pymia SOURCEDIR = source BUILDDIR = build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)jeolib-miallib-1.1.6/swig/python/doc/source/000077500000000000000000000000001467232417700207465ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/python/doc/source/1_intro.rst000077500000000000000000000011071467232417700230550ustar00rootroot00000000000000.. _Introduction: ============ Introduction ============ Organization of pyMIA --------------------- Modules ^^^^^^^ The pyMIA package is grouped in modules. A module combines a number of operations that belong together. The models defined pyMIA are: * io: input/output operations * geometry: operations that relate to geometry * geodesy: operations that relate to morphological geodesic transformations * pointop: pixel operations * dem: operations on digital elevation models Most of the morphological functions available in pyMIA are detailed in :cite:`soille2004sv`. jeolib-miallib-1.1.6/swig/python/doc/source/2_tutorial.rst000077500000000000000000000004601467232417700235670ustar00rootroot00000000000000.. _Tutorial: ######## Tutorial ######## .. toctree:: :maxdepth: 4 ******************************************************* Sources of documentation and help ******************************************************* This documentation is written using the `sphinx `_ tool. jeolib-miallib-1.1.6/swig/python/doc/source/3_reference.rst000077500000000000000000000023021467232417700236600ustar00rootroot00000000000000.. _Reference: ################ Reference Manual ################ .. toctree:: :maxdepth: 4 .. automodule:: convolve_base :members: .. automodule:: dist_base :members: .. automodule:: dist :members: .. automodule:: format_base :members: .. automodule:: format :members: .. automodule:: geometry_base :members: .. automodule:: geometry :members: .. automodule:: geodesy_base :members: .. automodule:: geodesy :members: .. automodule:: hmt_base :members: .. automodule:: label_base :members: .. automodule:: opclo_base :members: .. automodule:: erodil_base :members: .. automodule:: pointop_base :members: .. automodule:: pointop :members: .. automodule:: segment_base :members: .. automodule:: dem_base :members: .. automodule:: imem_base :members: .. automodule:: io_base :members: .. automodule:: stats_base :members: .. automodule:: proj :members: .. automodule:: visu :members: .. automodule:: stats_base :members: .. automodule:: stats :members: .. only:: html .. rubric:: Bibliographic references .. bibliography:: soille_public.bib jeolib-miallib-1.1.6/swig/python/doc/source/4_bibliography.rst000066400000000000000000000002711467232417700243760ustar00rootroot00000000000000.. _Bibliography: ############ Bibliography ############ .. toctree:: :maxdepth: 4 .. only:: html .. rubric:: Bibliographic references .. bibliography:: soille_public.bib jeolib-miallib-1.1.6/swig/python/doc/source/conf.py000077500000000000000000000126171467232417700222570ustar00rootroot00000000000000# -*- coding: utf-8 -*- # # pymia documentation build configuration file, created by # sphinx-quickstart on Wed Aug 21 21:43:04 2019. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # import os import sys sys.path.insert(0, os.path.abspath('.')) sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('../../build/lib.linux-x86_64-3.6/miallib')) sys.path.insert(0, os.path.abspath('./_templates')) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.coverage', 'sphinx.ext.imgmath', 'sphinx.ext.viewcode', 'sphinxcontrib.bibtex', 'sphinx.ext.autosummary'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The master toctree document. master_doc = 'index' # General information about the project. project = u'pymia' copyright = u'2019, European Union' author = u'Pierre.Soille@ec.europa.eu' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = u'0.9' # The full version, including alpha/beta/rc tags. release = u'0.9' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = [] # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # html_theme = 'alabaster' import sphinx_rtd_theme html_theme = "sphinx_rtd_theme" html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_show_sourcelink = False # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # This is required for the alabaster theme # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars html_sidebars = { '**': [ 'relations.html', # needs 'show_related': True theme option to display 'searchbox.html', ] } # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = 'pymialdoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'pymia.tex', u'pymia Documentation', u'Soille', 'manual'), ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'pymia', u'pymia Documentation', [author], 1) ] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'pymia', u'pymia Documentation', author, 'pymia', 'One line description of project.', 'Miscellaneous'), ] jeolib-miallib-1.1.6/swig/python/doc/source/dem-clean.bib000077500000000000000000000774231467232417700232710ustar00rootroot00000000000000%% %% Bibliography of papers dealing with DEMs. %% as read by Pierre Soille during the period 1988-> %% @InProceedings{ rieger92, author = {Rieger, W.}, title = {Automated river line and catchment area extraction for {DEM} data}, booktitle = {Proc. 17th ISPRS Congress}, pages = {642-649}, year = {1992}, volume = {28(B4)}, address = {Washington D.C.}, publisher = {IAPRS} } @Article{ rieger98, author = {Rieger, W.}, title = {A phenomenon-based approach to upslope contributing area and depressions in {DEM}s}, journal = {Hydrological Processes}, year = {1998}, volume = {12}, pages = {857-872}, doi = {10.1002/(SICI)1099-1085(199805)12:6} } @Article{ lindsay-creed2006, author = {Lindsay, J. and Creed, I.}, title = {Distinguishing actual and artefact depressions in digital elevation data}, journal = {Computers and Geosciences}, year = {2006}, volume = {32}, number = {8}, pages = {1192--1204}, doi = {10.1016/j.cageo.2005.11.002} } @Article{ zandbergen2006, author = {Zandbergen, P.}, title = {The effect of cell resolution on depressions in digital elevation models}, journal = {Appl. GIS}, year = {2006}, volume = {2}, number = {1}, pages = {4.1-4.35}, doi = {10.2104/ag060004} } @Article{ lindsay-creed2005, author = {Lindsay, J. and Creed, I.}, title = {Removal of artifact depressions from digital elevation models: Towards a minimum impact approach}, journal = {Hydrological Processes}, year = {2005}, volume = {19}, number = {16}, pages = {3113--3126}, doi = {10.1002/hyp.5835} } @InProceedings{ stepinski-collier2003, author = {Stepinski, T. and Collier, M.}, title = {Drainage densities of computationally extracted {M}artian drainage basins}, booktitle = {Proc. of Sixth International Conference on Mars}, year = {2003}, month = jul } @Article{ zevenbergen-thorne87, author = {Zevenbergen, L. and Thorne, C.}, title = {Quantitative analysis of land surface topography}, journal = {Earth Surface Processes and Landforms}, year = {1987}, volume = {12}, pages = {47-56} } @Article{ quinn-etal91, author = {Quinn, P. and Beven, K. and Chevallier, P. and Planchon, O.}, title = {The prediction of hillslope flow paths for distributed hydrological modelling using digital terrain models}, journal = {Hydrological Processes}, year = {1991}, volume = {5}, pages = {59--79} } @Article{ quinn-etal95, author = {Quinn, P. and Beven, K. and Lamb, R.}, title = {The $ln(a/\tan b)$ index: how to calculate it and how to use it in the {TOPMODEL} framework}, journal = {Hydrological Processes}, year = {1995}, volume = {9}, pages = {161-182} } @Article{ band89hp, author = {Band, L.}, title = {A terrain-based watershed information system}, journal = {Hydrological Processes}, year = {1989}, volume = {3}, pages = {151-162} } @TechReport{ bertolo2000, author = {Bertolo, F.}, title = {\htmladdnormallink{Catchment delineation and characterization: a review}{http://agrienv.jrc.it/publications/pdfs/CatchRev.pdf}}, institution = {Joint Research Centre of the European Commission}, year = {2000}, number = {EUR~19563~EN}, month = apr, url = {http://agrienv.jrc.it/publications/pdfs/CatchRev.pdf} } @TechReport{ colombo-vogt-bertolo2001, author = {Colombo, R. and Vogt, J. and Bertolo, F.}, title = {Deriving drainage networks and catchment boundaries at the {E}uropean scale: a new approach combibing digital elevation data and environmental characteristics}, institution = {Joint Research Centre of the European Commission}, year = {2001}, number = {EUR~19805~EN} } @Article{ mackay-band98, author = {Mackay, S. and Band, L.}, title = {Extraction and representation of nested catchment areas from digital elevation models in lake-dominated topography}, journal = {Water Resources Research}, year = {1998}, volume = {34}, number = {4}, pages = {897-901}, month = apr } @Article{ garbrecht-martz94, author = {Garbrecht, J. and Martz, L.}, title = {Grid size dependency of parameters extracted from digital elevation models}, journal = {Computers and Geosciences}, year = {1994}, volume = {20}, number = {1}, pages = {85-87} } @Unpublished{ saunders-maidment95, author = {Saunders, W. and Maidment, D.}, title = {Grid-based watershed and stream network delineation for {S}an {A}ntonio-{N}ueces coastal basin}, psbooktitle = {Paper presented at Proc. of Texas Water'95: {A} component Conference of the First International Conference of Water Resources Engineering}, psyear = {1995}, psmonth = aug } @Unpublished{ hellweger97, author = {Hellweger, F.}, title = {{AGREE} {DEM} surface reconditioning system}, year = {1997} } @Unpublished{ saunders99, author = {Saunders, W.}, title = {Preparation of {DEM}s for use in environmental modeling analysis}, psyear = {1999}, psmonth = jul } @Article{ cormack-etal93, author = {McCormack, J. and Gahegan, M. and Roberts, S. and Hogg, J. and Hoyle, B.}, title = {Feature-based derivation of drainage networks}, journal = {International Journal of Geographical Information Systems}, year = {1993}, volume = {7}, number = {3}, pages = {263-279} } @Article{ band89, author = {Band, L.}, title = {Automating topographic and ecounit extraction from mountainous forested watersheds}, journal = {AI APPLICATIONS}, year = {1989}, volume = {3}, number = {4}, pages = {1-9} } @Article{ garbrecht-martz93, author = {Garbrecht, J. and Martz, L.}, title = {Comment on "{A} combined algorithm for automated drainage network extraction" by {J}ean {C}horowicz et al.}, journal = {Water Resources Research}, year = {1993}, volume = {29}, number = {2}, pages = {535-536}, month = feb } @Article{ martz-garbrecht98, author = {Martz, L. and Garbrecht, J.}, title = {The treatment of flat areas and depressions in automated drainage analysis of raster digital elevation models}, journal = {Hydrological Processes}, year = {1998}, volume = {12}, pages = {843-855}, doi = {10.1002/(SICI)1099-1085(199805)12:6<843::AID-HYP658>3.0.CO;2-R} } @Article{ martz-garbrecht99, author = {Martz, L. and Garbrecht, J.}, title = {An outlet breaching algorithm for the treatment of closed depressions in a raster {DEM}}, journal = {Computers and Geosciences}, year = {1999}, volume = {25}, number = {7}, pages = {835-844}, doi = {10.1016/S0098-3004(99)00018-7} } @Article{ morris-heerdegen88, author = {Morris, D. and Heerdegen, R.}, title = {Automatically derived catchment boundaries and channel networks and their hydrological applications}, journal = {Geomorphology}, year = {1988}, volume = {1}, pages = {131-141}, doi = {10.1016/0169-555X(88)90011-6} } @Article{ wolock-price94, author = {Wolock, D. and Price, C.}, title = {Effects of Digital Elevation Model map scale and data resolution on a topography-based watershed model}, journal = {Water Resources Research}, year = {1994}, volume = {30}, number = {11}, pages = {3041-3052}, month = nov } @Article{ walker-willgoose99, author = {Walker, J. and Willgoose, G.}, title = {On the effect of digital elevation model accuracy on hydrology and geomorphology}, journal = {Water Resources Research}, year = {1999}, volume = {35}, number = {7}, pages = {2259-2268}, month = jul } @Article{ vogt-colombo-bertolo2003, author = {Vogt, J. and Colombo, R. and Bertolo, F.}, title = {Deriving drainage networks and catchment boundaries: a new methodology combining digital elevation data and environmental characteristics}, journal = {Geomorphology}, year = {2003}, volume = {53}, number = {3-4}, pages = {281-298}, month = jul, doi = {10.1016/S0169-555X(02)00319-7} } @Article{ tucker-bras98, author = {Tucker, G. and Bras, R.}, title = {Hillslopes, drainage density, and landscape morphology}, journal = {Water Resources Research}, year = {1998}, volume = {34}, number = {10}, pages = {2751-2764}, month = oct } @Article{ rinaldo-etal95wrr, author = {Rinaldo, A. and Vogel, G. and Rigon, R. and Rodriguez-Iturbe, I.}, title = {Can one gauge the shape of a basin?}, journal = {Water Resources Research}, year = {1995}, volume = {31}, number = {4}, pages = {1119-1127}, month = apr, doi = {10.1029/94WR03290} } @Article{ gibbard88, author = {Gibbard, P.}, title = {The history of the great northwest {E}uropean rivers during the past three million years}, journal = {Phil. Trans. R. Soc. Lond.}, year = {1988}, volume = {B~318}, pages = {559-602} } @Article{ tarboton-etal88, author = {Tarboton, D. and Bras, R. and Rodriguez-Iturbe, I.}, title = {The fractal nature of river networks}, journal = {Water Resources Research}, year = {1988}, volume = {24}, number = {8}, pages = {1317-1322}, month = aug } @Article{ tarboton-bras-iturbe89, author = {Tarboton, D. and Bras, R. and Rodriguez-Iturbe, I.}, title = {Scaling and elevation in river networks}, journal = {Water Resources Research}, year = {1989}, volume = {25}, pages = {2037-2051} } @Article{ tarboton-bras-iturbe91, author = {Tarboton, D. and Bras, R. and Rodriguez-Iturbe, I.}, title = {On the extraction of channel networks from digital elevation data}, journal = {Hydrological Processes}, year = {1991}, volume = {5}, pages = {81-100} } @Article{ tarboton-bras-iturbe92, author = {Tarboton, D. and Bras, R. and Rodriguez-Iturbe, I.}, title = {A physical basis for drainage density}, journal = {Geomorphology}, year = {1992}, volume = {5}, pages = {59-76}, doi = {10.1016/0169-555X(92)90058-V} } @Article{ tarboton97, author = {Tarboton, D.}, title = {A new method for the determination of flow directions and upslope areas in grid digital elevation models}, journal = {Water Resources Research}, year = {1997}, volume = {33}, number = {2}, pages = {309-319}, url = {http://www.engineering.usu.edu/dtarb/dinf.pdf}, month = feb, doi = {10.1029/96WR03137} } @Article{ rinaldo-etal95, author = {Rinaldo. A. and Dietrich, W. and Rigon, R. and Vogel, G. and Rodriguez-Iturbe, I.}, title = {Geomorphological signatures of varying climate}, journal = {Nature}, year = {1995}, volume = {374}, pages = {632-635}, month = apr } @Article{ zhang-montgomery94, author = {Zhang, W. and Montgomery, D}, title = {Digital elevation model grid size, landscape representation, and hydrologic simulations}, journal = {Water Resources Research}, year = {1994}, volume = {30}, pages = {1019-1028} } @Article{ zhang-etal2003, author = {Zhang, K. and Chen, S.-C. and Whitman, D. and Shyu, M.-L. and Yan, J. and Zhang, C.}, title = {A progressive morphological filter for removing nonground measurements form airborne {LIDAR} data}, journal = {IEEE Transactions on Geoscience and Remote Sensing}, year = {2003}, doi = {10.1109/TGRS.2003.810682}, volume = {41}, number = {4}, pages = {872-882}, month = apr } @Article{ chen-etal2007, author = {Chen Q. and Gong, P. and Baldocchi, D. and Xie, G.}, title = {Filtering airborne laser scanning data with morphological methods}, journal = {Photogrammetric Engineering and Remote Sensing}, year = {2007}, volume = {73}, number = {2}, pages = {175-185}, month = feb } @Article{ montgomery-dietrich89, author = {Montgomery, D. and Dietrich, W.}, title = {Source areas, drainage density, and channel initiation}, journal = {Water Resources Research}, year = {1989}, volume = {25}, number = {8}, pages = {1907-1918}, month = aug } @Article{ montgomery-foufoula93, author = {Montgomery, D. and Foufoula-Georgiou, E.}, title = {Channel network source representation using digital elevation models}, journal = {Water Resources Research}, year = {1993}, volume = {29}, pages = {3925-3934} } @Article{ cabrol-grin2001, author = {Cabrol, N. and Grin, E.}, title = {Composition of the drainage network on early {M}ars}, journal = {Geomorphology}, year = {2001}, volume = {37}, pages = {269-287} } @Article{ cabral-burges94, author = {Costa-Cabral, M. and Burges, S.}, title = {Digital elevation model networks {(\sc {D}EMON)}: a model of flow over hillslopes for computation of contributing and dispersal areas}, journal = {Water Resources Research}, year = {1994}, volume = {30}, number = {6}, pages = {1681-1692}, month = jun } @Article{ bevacqua-floris87, author = {Bevacqua, G. and Floris, R.}, title = {A surface specific-line tracking and slope recognition algorithm}, journal = {Computer Vision, Graphics, and Image Processing}, volume = {40}, number = {2}, pages = {219--227}, month = nov, year = {1987} } @Article{ band86, author = {Band, L.}, title = {Topographic partition of watersheds with digital elevation models}, journal = {Water Resources Research}, year = {1986}, volume = {22}, number = {1}, pages = {15-24}, month = jan } @Article{ hutchinson89, author = {Hutchinson, M.}, title = {A new procedure for gridding elevation and stream line data with automatic removal of spurious pits}, journal = {Journal of Hydrology}, year = {1989}, volume = {106}, pages = {211-232} } @Article{ taud-parrot-alvarez99, author = {Taud, H. and Parrot, J.-F. and Alvarez, R.}, title = {{DEM} generation by contour line dilation}, journal = {Computers and Geosciences}, year = {1999}, volume = {25}, pages = {775-783} } @Article{ renssen-knoop2000, author = {Renssen, H. and Knoop, J.}, title = {A global river routing network for use in hydrological modeling}, journal = {Journal of Hydrology}, year = {2000}, volume = {230}, pages = {230-243} } @TechReport{ mascardi98, author = {Mascardi, V.}, title = {Extraction of significant terrain features from {RSG} and {TIN}: a survey}, institution = {Universit\`a di Genova}, year = {1998} } @Article{ mark84, author = {Mark, D.}, title = {Automated detection of drainage networks from digital elevation models}, journal = {Cartographica}, year = {1984}, volume = {21}, pages = {168-178} } @Article{ callaghan-mark84, author = {O'Callaghan, J. and Mark, D.}, title = {The extraction of drainage networks from digital elevation data}, journal = {Computer Vision, Graphics, and Image Processing}, year = {1984}, volume = {28}, pages = {323-344} } @Article{ skidmore90, author = {Skidmore, A.}, title = {Terrain position as mapped from a gridded digital elevation model}, journal = {International Journal of Geographical Information Systems}, year = {1990}, volume = {4}, number = {1}, pages = {33-49} } @Article{ fowler-little79, author = {Fowler, R. and Little, J.}, title = {Automatic extraction of irregular network digital terrain models}, journal = {Computer Graphics}, year = {1979}, volume = {13}, number = {3}, pages = {199-207}, month = aug } @Article{ watson-etal85, author = {Watson, L. and Laffey, T. and Haralick, R.}, title = {Topographic classification of digital image intensity surfaces using generalized splines and the discrete cosine transformation}, journal = {Computer Vision, Graphics, and Image Processing}, volume = {29}, number = {2}, pages = {143--167}, month = feb, year = {1985} } @Article{ montgomery-dietrich88, author = {Montgomery, D. and Dietrich, W.}, title = {Where do channels begin?}, journal = {Nature}, year = {1988}, volume = {336}, pages = {232-234} } @Article{ montgomery-dietrich92, author = {Montgomery, D. and Dietrich, W.}, title = {Channel initiation and the problem of landscape scale}, journal = {Science}, year = {1992}, volume = {225}, pages = {826-830} } @Article{ tucker-etal2001, author = {Tucker, G. and Catani, F. and Rinaldo, A. and Bras, R.}, title = {Statistical analysis of drainage density from digital terrain data}, journal = {Geomorphology}, year = {2001}, volume = {36}, number = {3-4}, pages = {187-202}, month = feb, doi = {10.1016/S0169-555X(00)00056-8} } @Article{ desmet-govers96, author = {Desmet, P. and Gover, G.}, title = {Comparison of routing algorithms for digital elevation models and their implications for predicting ephemeral gullies}, journal = {International Journal of Geographical Information Systems}, year = {1996}, volume = {10}, number = {3}, pages = {311-331} } @Article{ howard94, author = {Howard, A.}, title = {A detachment-limited model of drainage basin evolution}, journal = {Water Resources Research}, year = {1994}, volume = {30}, number = {7}, pages = {2261-2285}, month = jul, doi = {10.1029/94WR00757} } @Article{ dunne80, author = {Dunne, T.}, title = {Formation and controls of channel networks}, journal = {Progress in Physical Geography}, year = {1980}, volume = {4}, pages = {211-239} } @Book{ rodriguez-iturbe-rinaldo97, author = {Rodriguez-Iturbe, I. and Rinaldo, A.}, title = {Fractal River Networks: Chance and Self-Organization}, publisher = {Cambridge University Press}, year = {1997} } @Article{ florinski98, author = {Florinski, I.}, title = {Combined analysis of digital terrain models and remotely sensed data in landscape investigations}, journal = {Progress in Physical Geography}, year = {1998}, volume = {22}, number = {1}, pages = {33-60} } @Article{ meisels-raizman-karnieli95, author = {Meisels, A. and Raizman, S. and Karnieli, A.}, title = {Skeletonizing a {DEM} into a drainage patterns}, journal = {Computers and Geosciences}, year = {1995}, volume = {21}, number = {1}, pages = {187-196} } @Misc{ tarboton-ames2001, author = {Tarboton, D. and Ames, D.}, title = {Advances in the mapping of flow networks from digital elevation data}, year = {2001} } @Article{ jones2002, author = {Jones, R.}, title = {Algorithms for using a {DEM} for mapping catchment areas of stream sediment samples}, journal = {Computers and Geosciences}, year = {2002}, volume = {28}, pages = {1051-1060} } @Article{ pike2000, author = {Pike, R.}, title = {Geomorphometry --- diversity in quantitative surface analysis}, journal = {Progress in Physical Geography}, year = {2000}, volume = {21}, number = {1}, pages = {1-20}, month = mar } @TechReport{ pike2002, author = {Pike, R.}, title = {A bibliography of terrain modelling (geomorphometry), the quantitative representation of topography---{S}upplement 4.0}, institution = {United States Geological Survey}, year = {2002}, number = {02-465}, url = {http://geopubs.wr.usgs.gov/open-file/of02-465/of02-465.pdf} } @Article{ finlayson-montgomery-2003, author = {Finlayson, D. and Montgomery, D.}, title = {Modeling large-scale fluvial erosion in geographic information systems}, journal = {Geomorphology}, year = {2003}, volume = {53}, pages = {147-164} } @InProceedings{ allister99, author = {McAllister, M.}, title = {A watershed algorithm for triangulated terrains}, booktitle = {Proceedings of the 11th Canadian Conference on Computational Geometry}, year = {1999}, address = {UBC, Vancouver, British Columbia, Canada}, month = {August 15-18}, url = {http://www.cs.ubc.ca/conferences/CCCG/elec_proc/fp50.pdf} } @Book{ wilson-gallant2000, author = {Wilson, J. and Gallant, J.}, title = {Terrain Analysis: Principles and Applications}, publisher = {John Wiley {\&} Sons}, year = {2000}, address = {New York} } @Article{ wilson2012, author = {Wilson, J.}, title = {Digital terrain modeling}, journal = {Geomorphology}, year = {2012}, doi = {10.1016/j.geomorph.2011.03.12}, volume = {137}, pages = {107-121} } @InProceedings{ tarboton2003, author = {Tarboton, D.}, title = {Terrain analysis using digital elevation models in hydrology}, booktitle = {Presented at the 23rd ESRI International Users Conference}, year = {2003}, address = {San Diego, California}, month = {July 7--11} } @Article{ moore-grayson-ladson91, author = {Moore, I. and Grayson, R. and Ladson, A.}, title = {Digital terrain modelling: a review of hydrological, geomorphological, and biological applications}, journal = {Hydrological Processes}, year = {1991}, volume = {5}, pages = {3-30} } @InCollection{ bloeschl-grayson2000, author = {Bl\"oschl, G. and Grayson, R.}, title = {Spatial observations and interpolation}, booktitle = {Spatial Patterns in Catchment Hydrology: Observations and Modelling}, pages = {17-50}, publisher = {Cambridge University Press}, year = {2000}, editor = {Grayson, R. and Bl\"oschl, G.}, address = {Cambridge, U.K.} } @Article{ verdin-verdin99, author = {Verdin, K. and Verdin, J.}, title = {A topological system for delineation and codification of the {E}arth's river basins}, journal = jhydro, year = {1999}, volume = {218}, pages = {1-12} } @Article{ stepinski-etal2004, author = {Stepinski, T. and Collier, M. and McGovern, P. and Clifford, S.}, title = {Martian geomorphology from fractal analysis of drainage networks}, journal = {Journal of Geophysical Research}, year = {2004}, volume = {109}, pages = {E02005}, doi = {10.1029/2003JE002098} } @Article{ mark-aronson84, author = {D. Mark and P.~Aronson}, title = {Scale-dependent dimensions of topographic surfaces}, journal = {Mathematical Geology}, year = {1984}, volume = {16}, number = {7}, pages = {671-683} } @InProceedings{ mark83, author = {Mark, D.}, title = {Automated detection of drainage networks from digital elevation models}, booktitle = {Proceedings of the Sixth International Symposium on Automated Cartography (Auto-Carto~VI)}, year = {1983}, pages = {288-298}, volume = {2}, address = {Ottawa, Canada} } @Article{ marks-dozier-frew84, author = {Marks, D. and Dozier, J. and Frew, J.}, title = {Automated basin delineation from digital elevation data}, journal = {Geo-Processing}, year = {1984}, volume = {2}, pages = {299-311} } @Article{ gauch-pizer93, author = {Gauch, J. and Pizer, S.}, title = {Multiresolution analysis of ridges and valleys in grey-scale images}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {1993}, volume = {15}, number = {6}, pages = {635-646}, month = jun } @Article{ peucker-douglas75, author = {Peucker, T. and Douglas, D.}, title = {Detection of surface-specific points by local parallel processing of discrete terrain elevation data}, journal = {Computer Graphics and Image Processing}, year = {1975}, volume = {4}, pages = {375-387} } @Article{ petersen-barrett-burton91, author = {S.~Petersen and W.~Barrett and R.~Burton}, title = {A system for automated interpolation and visualization of height grids from contour images}, journal = {Journal of Imaging Technology}, year = {1991}, volume = {17}, number = {4}, pages = {195-200} } @PhDThesis{ ansoult88phd, author = {Ansoult, M.}, title = {Etude et mod{\'e}lisation de formes de la surface terrestre}, school = {Université catholique de Louvain, Louvain-la-Neuve, Belgium}, year = {1988}, month = dec } @Article{ ansoult89, author = {Ansoult, M.}, title = {Circular sampling for {F}ourier analysis of digital terrain data}, journal = {Mathematical Geology}, year = {1989}, volume = {21}, number = {4}, pages = {401-410} } @InProceedings{ charleux-puech2000, author = {Charleux-Demargne, J. and Puech, C.}, title = {Quality assessment for drainage networks and watershed boudaries extraction from a digital elevation model}, booktitle = {Proc. of 8th ACM Symposium on GIS}, pages = {89-94}, year = {2000}, month = nov, psote = {extraction of network/watersheds after successive rotations and analysis of stability of result.} } @Article{ stewart98, author = {Stewart, A.}, title = {Fast horizon computation at all points of a terrain with visibility and shading applications}, journal = {IEEE Transactions on Visualization and Computer Graphics}, volume = {4}, number = {1}, pages = {82--93}, month = mar, year = {1998} } @Article{ mcmaster2002, author = {McMaster, K.}, title = {Effects of digital elevation model resolution on derived stream network positions}, journal = {Water Resources Research}, year = {2002}, doi = {10.1029/2000WR000150}, volume = {38}, number = {4}, pages = {13-1}, month = apr } @Article{ hofer-sapiro-wallner2006, author = {Hofer, M. and Sapiro, G. and Wallner, J.}, title = {Fair polyline networks for contrained smoothing of digital terrain elevation data}, journal = {IEEE Transactions on Geoscience and Remote Sensing}, year = {2006}, doi = {10.1109/TGRS.2006.875451}, volume = {44}, number = {10}, pages = {2983- 2990}, month = oct } @Book{ bono-etal2003, editor = {de Bono, A. and Del Pietro, D. and Giuliani, G. and Harayama, A. and Le Sourd, G. and Rizzolio, D.}, title = {\htmladdnormallink{Freshwater in {E}urope: Facts, Figures, and Maps}{http://www.grid.unep.ch/product/publication/freshwater_europe.php}}, publisher = {United Nations Environment Programme}, year = {2003}, url = {http://www.grid.unep.ch/product/publication/freshwater_europe.php} } @TechReport{ rodriguez-etal2006, author = {Rodr\'{\i}guez, E. and Morris, C. and Belz, J. and Chapin, E. and Martin, J. and Daffer, W. and Hensley, S.}, title = {An assessment of the {SRTM} topographic products}, institution = {NASA-Jet Propulsion Laboratory}, year = {2006}, url = {http://www2.jpl.nasa.gov/srtm/SRTM_D31639.pdf}, number = {JPL D-31639} } @TechReport{ dma96, author = {DMA}, title = {Performance Specification Digital Elevation Data ({DTED})}, institution = {National Imaging and Mapping Agency}, year = {1996}, number = {MIL-PRF-89020A}, address = {U.S.A.}, month = apr } @TechReport{ dma2000, author = {DMA}, title = {Performance Specification Digital Elevation Data ({DTED})}, institution = {National Imaging and Mapping Agency}, year = {2000}, number = {MIL-PRF-89020B}, address = {U.S.A.}, month = apr, url = {http://www.nga.mil/ast/fm/acq/89020B.pdf} } @Book{ peckham-jordan2007, title = {Digital Terrain Modelling}, subtitle = {Development and Applications in a Policy Support Environment}, publisher = {Springer-Verlag}, year = {2007}, editor = {Peckham, R. and Jordan, G.}, series = {Lecture Notes in Geoinformation and Cartography}, url = {http://www.springer.com/east/home/geosciences?SGWID=5-10006-69-173624747-0} } @Book{ hengl-reuter2008, editor = {Hengl, T. and Reuter, H.}, title = {Geomorphometry: Concepts, Software, Applications}, publisher = {Elsevier}, year = {2008}, url = {http://www.elsevierdirect.com/product.jsp?isbn=9780123743459&ref=CWS1#6}, volume = {33}, series = {Developments in Soil Science}, address = {Amsterdam}, month = oct } @Book{ li-zhu-gold2005, author = {Li, Z. and Zhu, Q. and Gold, C.}, title = {Digital Terrain Modelling: Principles and Methodology}, publisher = {CRC Press}, year = {2005}, address = {Boca Raton, Florida} } @Book{ maune2001, editor = {Maune, D.}, title = {Digital Elevation Model Technologies and Applications: The {DEM} users Manual}, publisher = {The American Society for Photogrammetry and Remote Sensing}, year = {2001}, address = {Bethesda, Maryland} } @InProceedings{ grazzini-chrysoulakis2005, author = {Grazzini, J. and Chrysoulakis, N.}, title = {Extraction of surface properties from a high accuracy {DEM} using multiscale remote sensing techniques}, booktitle = {Proc. of EnviroInfo}, pages = {352-356}, address = {Brno, Czech Republic}, year = {2005} } @Misc{ reuter-etal2008prep, author = {H. Reuter and P. Strobl and W. Mehl and A. Jarvis and A. Nelson and R. Seliger}, title = {Methods for Data Fusion for a Global 30m Digital Surface Model}, howpublished = {In preparation}, year = {2008} } @Misc{ reuter-etal2008aster, author = {H. Reuter and P. Strobl and W. Mehl and A. Jarvis and A. Nelson and R. Seliger}, title = {1 arc second {DEM} based on {ASTER} data V1.0}, howpublished = {European Commission - DG Joint Research Centre (JRC) and and International Centre for Tropical Agriculture (CIAT)}, year = {2008}, url = {http://srtm.jrc.it} } @InProceedings{ hovenbitzer2008, author = {Hovenbitzer, M.}, title = {The {E}uropean {DEM} ({EuroDEM})}, url = {http://www.isprs.org/congresses/beijing2008/proceedings/4_pdf/323.pdf}, booktitle = {The International Archives of the Photogrammetry, Remote Sensing and Spatial Information Sciences}, pages = {1853-1856}, year = {2008}, volume = {XXXVII} } @Article{ horn81, author = {Horn, B.}, title = {Hill shading and the reflectance map}, journal = {Proceedings of the IEEE}, year = {1981}, url = {http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=1456186&isnumber=31297}, volume = {69}, number = {1}, pages = {14-47}, month = jan } @Article{ rodriguez-morris-belz2006, author = {Rodr\'{\i}guez, E. and Morris, C. and Belz, J.}, year = {2006}, title = {A global assessment of the {SRTM} performance}, journal = {Photogrammetric Engineering and Remote Sensing}, volume = {72}, number = {3}, pages = {249-260} } @Article{ tianqi-etal2003, author = {AO TIANQI, KUNIYOSHI TAKEUCHI, HIROSHI ISHIDAIRA, JUNICH YOSHITANI & KAZUHIKO FUKAMIc}, title = {Development and application of a new algorithm for automated pit removal for grid DEMs}, journal = {Hydrological Sciences Journal }, year = {2003}, doi = {10.1623/hysj.48.6.985.51423}, volume = {48}, number = {6}, pages = {985-997}, month = dec } @Article{ grimaldi-etal2007, title = {A physically-based method for removing pits in digital elevation models}, journal = {Advances in Water Resources}, volume = {30}, number = {10}, pages = {2151 - 2158}, year = {2007}, issn = {0309-1708}, doi = {10.1016/j.advwatres.2006.11.016}, url = {http://www.sciencedirect.com/science/article/pii/S0309170807000644}, author = {Salvatore Grimaldi and Fernando Nardi and Francesco Di Benedetto and Erkan Istanbulluoglu and Rafael L. Bras} } @Article{ callow-etal2007jh, author = {Callow, J. and Van Niel, K. and Boggs, G.}, title = {How does modifying a {DEM} to reflect known hydrology affect subsequent terrain analysis}, journal = {Journal of Hydrology}, year = {2007}, doi = {10.1016/j.hydrol.2006.06.020}, volume = {332}, pages = {20-39} } @Article{ schwanghart-etal2013, author = {Schwanghart, W. and Groom, G. and Kuhn, N. and Heckrath, G.}, title = {Flow network derivation from high resolution {DEM} in a low relief, agrarian landscape}, journal = {Earth Surface Processes and Landforms}, year = {2013}, key = {10.1002/esp.3452} } @InProceedings{ abreu-etal2012, author = {Abreu, E. and Rosim, S. and Renno, C., Oliveira, J. and Jardim, A. and Ortiz, J. and Dutra, L.}, title = {TerraHidro}, booktitle = {Proc. IGARSS}, pages = {546-549}, year = {2012} } @InProceedings{ takadu-tadono2017, author = {J. Takaku and T. Tadono}, booktitle = {2017 IEEE International Geoscience and Remote Sensing Symposium (IGARSS)}, title = {Quality updates of {AW3D} global {DSM} generated from {ALOS} {PRISM}}, year = {2017}, volume = {}, number = {}, pages = {5666-5669}, doi = {10.1109/IGARSS.2017.8128293}, issn = {2153-7003}, month = {July} } jeolib-miallib-1.1.6/swig/python/doc/source/index.rst000077500000000000000000000007531467232417700226170ustar00rootroot00000000000000.. pymia documentation master file, created by sphinx-quickstart on Wed Aug 21 21:43:04 2019. You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Welcome to pymia's documentation! ================================= .. toctree:: :maxdepth: 2 :caption: Contents: 1_intro 2_tutorial 3_reference 4_bibliography Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` jeolib-miallib-1.1.6/swig/python/doc/source/soille_public.bib000077500000000000000000003741151467232417700242670ustar00rootroot00000000000000 @MastersThesis{ soille88, author = {Soille, P.}, title = {Mod\`eles Num\'eriques de Terrain et Morphologie Math\'ematique~: D\'elimitation Automatique de Bassins Versants}, school = {Université catholique de Louvain, Louvain-la-Neuve, Belgium}, year = {1988}, month = jun } @InProceedings{ soille89ulm, author = {Soille, P.}, title = {Mod\`eles num\'eriques de terrain et morphologie math\'ematique~: d\'elimitation automatique de bassins versants}, booktitle = {2èmes Journées Utilités et Limites des Modèles en Hydrologie}, year = {1989}, publisher = {ORSTOM}, address = {Montpellier, France}, pages = {12-13} } @InProceedings{ soille90ulm, author = {Soille, P.}, title = {Génération de {MNT} à partir de fonctions distances}, booktitle = {3èmes Journées Utilités et Limites des Modèles en Hydrologie}, location = {Montpellier}, editor = {Depraetere, C.}, year = {1990}, publisher = {ORSTOM}, address = {Montpellier}, pages = {1-14} } @InProceedings{ soille-vincent90, author = {Soille, P. and Vincent, L.}, title = {Determining watersheds in digital pictures via flooding simulations}, booktitle = {Visual Communications and Image Processing'90}, location = {Lausanne}, editor = {Kunt, M.}, year = {1990}, volume = {1360}, pages = {240-250}, publisher = {Society of Photo-Instrumentation Engineers}, doi = {10.1117/12.24211}, address = {Bellingham} } @Article{ soille-ansoult90, author = {Soille, P. and Ansoult, M.}, title = {Automated basin delineation from Digital Elevation Models using mathematical morphology}, doi = {10.1016/0165-1684(90)90127-K}, journal = {Signal Processing}, year = {1990}, volume = {20}, pages = {171-182}, month = jun } @Article{ ansoult-soille-loodts90, author = {Ansoult, M. and Soille, P. and Loodts, J.}, title = {Mathematical Morphology: a tool for automated {GIS} data acquisition from scanned thematic maps}, journal = {Photogrammetric Engineering and Remote Sensing}, year = {1990}, volume = {56}, number = {9}, pages = {1263-1271}, month = sep, url = {https://eserv.asprs.org/PERS/1990journal/sep/1990_sep_1263-1271.pdf} } @Article{ soille91, author = {Soille, P.}, title = {Spatial distributions from contour lines: an efficient methodology based on distance transformations}, journal = {Journal of Visual Communication and Image Representation}, year = {1991}, volume = {2}, number = {2}, pages = {138-150}, month = jun, doi = {10.1016/1047-3203(91)90004-Y} } @Article{ vincent-soille91, author = {Vincent, L. and Soille, P.}, title = {Watersheds in digital spaces: an efficient algorithm based on immersion simulations}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {1991}, volume = {13}, number = {6}, pages = {583-598}, month = jun, doi = {10.1109/34.87344}, optabstract = {http://computer.org/tpami/tp1991/i0583abs.htm} } @PhDThesis{ soille92phd, author = {Soille, P.}, title = {Morphologie Mathématique~: du Relief à la Dimensionalité ---Algorithmes et Méthodes---}, school = {Université catholique de Louvain~; en collaboration avec l'Ecole des Mines de Paris}, year = {1992}, month = feb } @Booklet{ soille-rivest92, author = {Soille, P. and Rivest, J.-F.}, title = {Principles and applications of morphological image analysis}, howpublished = {Tutorial booklet of the 11th IAPR {I}nternational {C}onference on {P}attern {R}ecognition, Den Haag}, time = {29 August 1992}, month = aug, year = {1992} } @InProceedings{ rivest-soille-beucher92, author = {Rivest, J.-F. and Soille, P. and Beucher, S.}, title = {Morphological gradients}, booktitle = {Nonlinear image processing~III}, editor = {Dougherty, E. and Astola, J. and Boncelet, G.}, year = {1992}, volume = {1658}, publisher = {Society of Photo-Instrumentation Engineers}, doi = {10.1117/12.58373}, month = feb, pages = {139-150} } @Article{ rivest-serra-soille92, author = {Rivest, J.-F. and Serra, J. and Soille, P.}, title = {Dimensionality in image analysis}, journal = {Journal of Visual Communication and Image Representation}, doi = {10.1016/1047-3203(92)90011-H}, year = {1992}, pages = {137-146}, volume = {3}, number = {2} } @Article{ soille92, author = {Soille, P.}, title = {Partitioning of multispectral images using mathematical morphology}, journal = {Vision {\&} Voice Magazine}, pages = {283-293}, volume = {6}, number = {4}, year = {1992} } @InProceedings{ tuzikov-soille-jeulin92, title = {Extraction of grid lines on stamped metal pieces using mathematical morphology}, author = {Tuzikov, A. and Soille, P. and Jeulin, D. and Bruneel, H. and Vermeulen, M.}, year = {1992}, doi = {10.1109/ICPR.1992.201591}, booktitle = {Proc. 11th IAPR International Conference on Pattern Recognition, Conference A: Computer Vision and Applications}, volume = {1}, pages = {425-428}, address = {The Hague}, month = sep } @InProceedings{ soille-serra-rivest92, author = {Soille, P. and Serra, J. and Rivest, J.-F.}, title = {Dimensional measurements and operators in mathematical morphology}, booktitle = {Nonlinear image processing~III}, editor = {Dougherty, E. and Astola, J. and Boncelet, G.}, year = {1992}, volume = {1658}, publisher = {Society of Photo-Instrumentation Engineers}, month = feb, doi = {10.1117/12.58372}, pages = {127-138} } @Article{ rivest-soille-beucher93, author = {Rivest, J.-F. and Soille, P. and Beucher, S.}, title = {Morphological gradients}, journal = {Journal of Electronic Imaging}, month = oct, volume = {2}, number = {4}, pages = {326-336}, year = {1993}, doi = {10.1117/12.159642} } @InProceedings{ soille93a, author = {Soille, P.}, title = {The geodesic time function: {P}rinciples and applications}, booktitle = {The 1993 International Conference on Confocal Microscopy {\&} {3D} Image Processing}, year = {1993}, pages = {107}, address = {Sydney}, month = feb } @InCollection{ soille93b, author = {Soille, P.}, title = {Partitioning of multispectral images using mathematical morphology}, booktitle = {Vision Jahrbuch 1993}, publisher = {European Media Service}, address = {Witzmannsberg, Germany}, year = {1993}, editor = {Oehrl, S.}, pages = {II.33--II.43} } @InProceedings{ breen-soille93, author = {Breen, E. and Soille, P.}, title = {Generalization of van {H}erk recursive erosion/dilation algorithm to lines at arbitrary angles}, booktitle = {Proc. DICTA'93: Digital Image Computing: Techniques and Applications}, year = {1993}, editor = {Fung, K. and Ginige, A.}, pages = {549-555}, publisher = {Australian Pattern Recognition Society}, address = {Sydney}, month = dec } @InProceedings{ soille-rivest93, author = {Soille, P. and Rivest, J.-F.}, title = {Dimensionality of morphological operators and cluster analysis}, booktitle = {Image algebra and morphological image processing IV}, volume = {2030}, publisher = {Society of Photo-Instrumentation Engineers}, doi = {10.1117/12.146676}, editor = {Dougherty, E. and Gader, P. and Serra, J.}, year = {1993}, pages = {43-53}, month = jul } @Article{ soille94, author = {Soille, P.}, title = {Generalized geodesy via geodesic time}, journal = {Pattern Recognition Letters}, volume = {15}, number = {12}, pages = {1235-1240}, month = dec, year = {1994}, doi = {10.1016/0167-8655(94)90113-9} } @InCollection{ soille94perso, author = {Soille, P.}, title = {Generalized geodesic distances applied to interpolation and shape description}, booktitle = {Mathematical Morphology and its Applications to Image Processing}, doi = {10.1007/978-94-011-1040-2_25}, publisher = {Kluwer Academic Publishers}, year = {1994}, editor = {Serra, J. and Soille, P.}, series = {Computational Imaging and Vision}, volume = {2}, pages = {193-200} } @Book{ serra-soille94aperso, title = {Mathematical Morphology and its Applications to Image Processing}, publisher = {Kluwer Academic Publishers}, year = {1994}, editor = {Serra, J. and Soille, P.}, series = {Computational Imaging and Vision}, volume = {2}, address = {Dordrecht}, doi = {10.1007/978-94-011-1040-2} } @Book{ serra-soille94bperso, title = {{ISMM}'94: {M}athematical Morphology and its Applications to Image Processing ---{P}oster contributions---}, publisher = {Ecole des Mines de Paris}, year = {1994}, editor = {Serra, J. and Soille, P.} } @InProceedings{ soille-rivest94perso, author = {Soille, P. and Rivest, J.-F.}, title = {On the robustness of fractal dimension measurements in image analysis}, booktitle = {{ISMM}'94: {M}athematical morphology and its applications to image processing ---{P}oster Contributions---}, year = {1994}, editor = {Serra, J. and Soille, P.}, pages = {25--26}, publisher = {Ecole des Mines de Paris}, month = sep } @Article{ soille-gratin94, author = {Soille, P. and Gratin, C.}, title = {An efficient algorithm for drainage networks extraction on {DEM}s}, journal = {Journal of Visual Communication and Image Representation}, year = {1994}, month = jun, volume = {5}, number = {2}, pages = {181-189}, doi = {10.1006/jvci.1994.1017} } @Article{ soille-nickolay-koeppen94, author = {Soille, P. and Nickolay, B. and Köppen, M.}, title = {A modular system for image segmentation based on watershed transformation}, journal = {Vision Magazine}, pages = {118-120}, volume = {94}, number = {2}, year = {1994} } @InProceedings{ rivest-soille94, author = {Rivest, J.-F. and Soille, P.}, title = {Physical significance of measurements in images}, booktitle = {Proc. IEEE Instrumentation and Measurement Technology Conference}, year = {1994}, pages = {1431-1434}, address = {Hamamatsu}, month = may, doi = {10.1109/IMTC.1994.352165} } @InProceedings{ peyrard-etal95, author = {Peyrard, R. and Soille, P. and Klein, J.-C. and Tuzikov, A.}, title = {A dedicated hardware system for the extraction of grid patterns on stamped metal sheets}, booktitle = {Proc. of 1995 IEEE Workshop on Nonlinear Signal and Image Processing}, year = {1995}, editor = {Pitas, I.}, address = {Neos Marmaras}, pages = {867-870}, oldurl = {http://poseidon.csd.auth.gr/Workshop/papers/p_34_3.html}, month = jun } @InProceedings{ soille-breen-jones95, author = {Soille, P. and Breen, E. and Jones, R.}, title = {A fast algorithm for min/max filters along lines of arbitrary orientation}, booktitle = {Proc. of 1995 IEEE Workshop on Nonlinear Signal and Image Processing}, year = {1995}, editor = {Pitas, I.}, address = {Neos Marmaras}, pages = {987-990}, month = jun } @Article{ rivest-soille95, author = {Rivest, J.-F. and Soille, P.}, title = {Physical significance of image measurements}, journal = {IEEE Transactions on Instrumentation and Measurements}, year = {1995}, volume = {44}, number = {3}, pages = {751-754}, month = jun, doi = {10.1109/19.387324} } @Article{ soille96jei, author = {Soille, P.}, title = {Morphological partitioning of multispectral images}, journal = {Journal of Electronic Imaging}, year = {1996}, volume = {5}, number = {3}, pages = {252-265}, month = jul, doi = {10.1117/12.240258} } @InProceedings{ soille96b, author = {Soille, P.}, title = {Morphological Image Processing}, editor = {Parkin, R. and Lima, M. and King, T.}, pages = {25--36}, booktitle = {Proceedings of the Euro Conference Vision and Control Aspects of Mechatronics}, year = {1996}, address = {Guimar\~aes, Portugal}, isbn = {ISBN 972-8063-07-5} } @Article{ soille-rivest96, author = {Soille, P. and Rivest, J.-F.}, title = {On the validity of fractal dimension measurements in image analysis}, journal = {Journal of Visual Communication and Image Representation}, year = {1996}, volume = {7}, number = {3}, pages = {217--229}, month = sep, doi = {10.1006/jvci.1996.0020} } @InCollection{ rivest-soille-beucher96, author = {Rivest, J.-F. and Soille, P. and Beucher, S.}, title = {Morphological gradients}, booktitle = {Selected Papers on Morphological Image Processing: {P}rinciples and Optoelectronic Implementations}, publisher = {Society for Photo-Optical Instrumentation Engineers}, year = {1996}, editor = {Szoplik, T.}, volume = {MS~127}, series = {SPIE Milestones Series}, pages = {295--305}, isbn = {ISBN 0-8194-2284-3} } @Misc{ soille96cdrom, author = {Soille, P.}, title = {Analyse d'images appliquée au traitement des données de terrain}, howpublished = {CDROM des VIèmes Entretiens d'Agropolis, Atelier~1}, address = {Montpellier}, year = {1996} } @InProceedings{ soille96agro, author = {Soille, P.}, title = {Analyse d'images appliquée au traitement des données de terrain}, pages = {21}, booktitle = {VIèmes entretiens {AGROPOLIS}}, year = {1996}, address = {Montpellier} } @Article{ soille-breen-jones96, author = {Soille, P. and Breen, E. and Jones, R.}, title = {Recursive implementation of erosions and dilations along discrete lines at arbitrary angles}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {1996}, month = may, pages = {562-567}, volume = {18}, number = {5}, doi = {10.1109/34.494646}, url = {http://www.computer.org/tpami/tp1996/i0562abs.htm} } @InCollection{ jones-soille96a, author = {Jones, R. and Soille, P.}, title = {Periodic lines and their applications to granulometries}, editor = {Maragos, P. and Schafer, W. and Butt, M.}, pages = {264-272}, booktitle = {Mathematical Morphology and its Applications to Image and Signal Processing}, year = {1996}, publisher = {Kluwer Academic Publishers}, series = {Computational Imaging and Vision}, volume = {5}, doi = {10.1007/978-1-4613-0469-2_30} } @Article{ jones-soille96b, author = {Jones, R. and Soille, P.}, title = {Periodic lines: definition, cascades, and application to granulometries}, journal = {Pattern Recognition Letters}, year = {1996}, volume = {17}, number = {10}, pages = {1057--1063}, month = sep, doi = {10.1016/0167-8655(96)00066-9} } @InProceedings{ soille97a, author = {Soille, P.}, title = {Geodesic transformations and metrics: an overview}, editor = {Banon, G.}, pages = {1--48}, booktitle = {Brazilian Workshop'97 on Mathematical Morphology, mini-course~II}, year = {1997}, organization = {Instituto Nacional de Pesquisas Espaciais}, address = {CP 515, CEP 12201-970 São José dos Campos, SP, Brazil}, month = feb } @InProceedings{ soille97b, author = {Soille, P.}, title = {From half-plane closings to convex hulls}, editor = {Banon, G.}, pages = {2}, booktitle = {Brazilian Workshop'97 on Mathematical Morphology}, year = {1997}, organization = {Instituto Nacional de Pesquisas Espaciais}, address = {CP 515, CEP 12201-970 São José dos Campos, SP, Brazil}, month = feb, oldurl = {http://www.inpe.br/~banon/URLib2/col/dpi.inpe.br/banon/1997/02.03.20.07/doc/tag.html} } @InProceedings{ soille97c, author = {Soille, P.}, title = {Segmentation of multispectral images using mathematical morphology}, editor = {Banon, G.}, pages = {2}, booktitle = {Brazilian Workshop'97 on Mathematical Morphology}, year = {1997}, organization = {Instituto Nacional de Pesquisas Espaciais}, address = {CP 515, CEP 12201-970 São José dos Campos, SP, Brazil}, month = feb, oldurl = {http://www.inpe.br/~banon/URLib2/col/dpi.inpe.br/banon/1996/10.18.18.28/doc/tag.html} } @Booklet{ soille97hdr, author = {Soille, P.}, title = {Analyse d'images par la morphologie mathématique}, howpublished = {Thèse d'habilitation à diriger des recherches, Université Montpellier~II, France}, year = {1997}, month = {Mars} } @InCollection{ soille98a, author = {Soille, P.}, booktitle = {Mathematical Morphology and its Applications to Image and Signal Processing}, title = {Morphological unwrapping of interferometric phase-maps}, publisher = {Kluwer Academic Publishers}, year = {1998}, editor = {Heijmans, H. and Roerdink, J.}, pages = {383--390}, volume = {12}, series = {Computational Imaging and Vision}, address = {Dordrecht} } @InCollection{ soille98b, author = {Soille, P.}, booktitle = {Mathematical Morphology and its Applications to Image and Signal Processing}, title = {Grey scale convex hulls: definition, implementation, and application}, publisher = {Kluwer Academic Publishers}, year = {1998}, editor = {Heijmans, H. and Roerdink, J.}, pages = {83--90}, volume = {12}, series = {Computational Imaging and Vision}, address = {Dordrecht} } @Booklet{ soille98c, author = {Soille, P.}, title = {Mathematical morphology for image analysis and pattern recognition}, howpublished = {Tutorial booklet of the 14th IAPR {I}nternational {C}onference on {P}attern {R}ecognition, {B}risbane}, month = aug, time = {August 16 1998}, year = {1998} } @Book{ soille98d, author = {Soille, P.}, title = {Morphologische Bildverarbeitung}, subtitle = {Grundlagen, {M}ethoden, {A}nwendungen}, publisher = {Springer-Verlag}, doi = {10.1007/978-3-642-72190-8}, year = {1998}, isbn = {3-540-64323-0}, address = {Berlin, Heidelberg} } @InProceedings{ talbot-soille98, author = {Talbot, H. and Soille, P.}, title = {Advances in Directional Image Analysis using {MM}}, editor = {Uylings, H.}, pages = {48}, booktitle = {7th European Congress for Stereology}, year = {1998}, address = {Amsterdam}, month = apr } @InProceedings{ soille-talbot98, author = {Soille, P. and Talbot, H.}, title = {Image structure orientation using mathematical morphology}, doi = {10.1109/ICPR.1998.711982}, editor = {Jain, A. and Venkatesh, S. and Lovell, B.}, pages = {1467-1469}, volume = {2}, booktitle = {14th International Conference on Pattern Recognition}, year = {1998}, optorganization={IAPR}, publisher = {IEEE Computer Society}, address = {Brisbane}, month = aug } @InProceedings{ whelan-soille98, author = {Whelan, P. and Soille, P.}, title = {Watermark extraction in paper samples}, editor = {Vernon, D.}, pages = {287-299}, booktitle = {Proc. Optical Engineering Society of Ireland {\&} Irish Machine Vision and Image Processing Joint Conference}, year = {1998}, address = {National University of Ireland, Maynooth}, month = sep } @InProceedings{ koeppen-ruiz-soille98, author = {Köppen, M. and {Ruiz-del-Solar}, J. and Soille, P.}, title = {Texture Segmentation by Biologically-Inspired Use of Neural Networks and Mathematical Morphology}, editor = {Heiss, M.}, pages = {267-272}, booktitle = {NC'98, International ICSC/IFAC Symposium on Neural Computation}, year = {1998}, publisher = {ICSC Academic Press}, address = {Wien}, url = {http://www.vision.fhg.de/ipk/publikationen/pdf/nc98.pdf}, month = sep } @Book{ soille99, author = {Soille, P.}, title = {Morphological Image Analysis}, subtitle = {Principles and Applications}, publisher = {Springer-Verlag}, year = {1999}, optisbn = {3-540-65671-5}, address = {Berlin, New York} } @Article{ ranwez-soille99, author = {Ranwez, V. and Soille, P.}, title = {Order independent homotopic thinning}, opteditor = {Bertrand, G. and Couprie, M. and Perroton, L.}, journal = {Lecture Notes in Computer Science}, volume = {\htmladdnormallink{1568}{http://link.springer.de/link/service/series/0558/tocs/t2301.htm}}, pages = {337-346}, doi = {10.1007/3-540-49126-0}, optbooktitle = {Proc. of Discrete Geometry for Computer Imagery'99}, year = {1999}, publisher = {Springer-Verlag} } @InProceedings{ arrighi-soille99, author = {Arrighi, P. and Soille, P.}, title = {From scanned topographic maps to digital elevation models}, booktitle = {Proc. of Geovision'99: {I}nternational Symposium on Imaging Applications in Geology}, pages = {1--4}, year = {1999}, editor = {Jongmans, D. and Pirard, E. and Trefois, P.}, month = may, publisher = {Université de Liège, Belgium} } @InProceedings{ soille99wta98, author = {Soille, P.}, title = {Morphological texture analysis: a survey}, editor = {Burkhardt, H.}, editor-url = {http://www.informatik.uni-freiburg.de/~lmb/people/burkhardt/index.html}, booktitle = {Proc. of WTA'98: Workshop on Texture Analysis 1998}, chapter = {14}, year = {1999}, pages = {193--207}, publisher = {Albert-Ludwigs-Universität, Institut für Informatik}, publisher-url = {http://www.informatik.uni-freiburg.de}, address = {Freiburg im Breisgau}, month = mar } @InCollection{ soille99hbcv1, author = {Soille, P.}, title = {Morphological Operators}, booktitle = {Handbook of Computer Vision and Applications}, publisher = {Academic Press}, year = {1999}, editor = {Jähne, B. and Haußecker, H. and Geißler, P.}, volume = {2}, chapter = {21}, pages = {627-682}, address = {San Diego} } @InCollection{ soille99hbcv2, author = {Soille, P.}, title = {Applications of Morphological Operators}, booktitle = {Handbook of Computer Vision and Applications}, publisher = {Academic Press}, year = {1999}, editor = {Jähne, B. and Haußecker, H. and Geißler, P.}, volume = {3}, chapter = {12}, pages = {283-296}, address = {San Diego} } @InCollection{ soille99hbcv3, author = {Soille, P.}, title = {Processing of Digital Elevation Maps}, booktitle = {Handbook of Computer Vision and Applications}, publisher = {Academic Press}, year = {1999}, editor = {Jähne, B. and Haußecker, H. and Geißler, P.}, volume = {3}, chapter = {19}, pages = {411-428}, address = {San Diego} } @InProceedings{ drimbarean-soille-whelan99, author = {Drimbarean, A. and Soille, P. and Whelan, P.}, title = {Online registration of watermarks from continuous web paper}, booktitle = {Proc. of Irish Machine Vision and Image Processing Conference}, pages = {267-279}, year = {1999}, editor = {Whelan, P.}, organization = {Irish Pattern Recognition Society}, publisher = {Dublin City University} } @InProceedings{ koeppen-soille99, author = {Köppen, M. and Soille, P.}, title = {Two-dimensional frameworks for the application of soft computing to image processing}, booktitle = {Proceedings of International Workshop on Soft Computing in Industry'99}, publisher = {Nagoya University}, editor = {Suzuki, Y.}, doi = {10.1007/978-1-4471-0509-1_45}, pages = {204--209}, year = {1999}, address = {Muroran, Hokkaido, Japan} } @InProceedings{ soille99spie, author = {Soille, P.}, title = {Unwrapping of phase maps using mathematical morphology}, booktitle = {Proceedings of {EOS/SPIE} International Symposia on Industrial Lasers and Inspection {\&} Envirosense ---Conference on Laser Metrology and Inspection---}, pages = {84--93}, year = {1999}, editor = {Tiziani, H. and Rastogi, P.}, volume = {3823}, location = {München}, month = jun, publisher = {Society of Photo-Instrumentation Engineers}, doi = {10.1117/12.360970}, address = {Bellingham} } @Article{ soille2000fi, author = {Soille, P.}, title = {From binary to grey scale convex hulls}, journal = {Fundamenta Informaticae}, year = {2000}, volume = {41}, number = {1--2}, pages = {131-146}, month = jan, doi = {10.3233/FI-2000-411205} } @Article{ soille2000ole, author = {Soille, P.}, title = {Morphological phase unwrapping}, journal = {Optics and Lasers in Engineering}, year = {2000}, volume = {32}, number = {4}, pages = {339-352}, doi = {10.1016/S0143-8166(00)00006-3} } @InProceedings{ soille2000lugano, author = {Soille, P.}, title = {Morphological Image Analysis for Optical Nondestructive Testing}, editor = {Rastogi, P. and Inaudi, D.}, pages = {375-386}, booktitle = {Proc. of Int. Conf. on Trends in Optical Nondestructive Testing}, address = {Lugano}, year = {2000}, month = may, publisher = {Ecole Polytechnique Fédérale de Lausanne} } @InCollection{ soille2000cva, author = {Soille, P.}, title = {Morphological Operators}, booktitle = {Computer Vision and Applications: A Guide for Students and Practitioners}, publisher = {Academic Press}, year = {2000}, editor = {Jähne, B. and Haußecker, H.}, pages = {483-515}, chapter = {14}, address = {San Diego}, doi = {10.1016/B978-012379777-3/50015-7} } @Article{ soille2000ivc, author = {Soille, P.}, title = {Morphological image analysis applied to crop field mapping}, journal = {Image and Vision Computing}, year = {2000}, volume = {18}, number = {13}, pages = {1025-1032}, month = oct, doi = {10.1016/S0262-8856(00)00043-3} } @InCollection{ soille2000ios, author = {Soille, P.}, title = {From binary to grey scale convex hulls}, booktitle = {Mathematical Morphology}, publisher = {IOS Press}, year = {2000}, editor = {Goutsias, J. and Heijmans, H.}, pages = {131-146.}, address = {Amsterdam} } @Article{ soille2000dgci, author = {Soille, P.}, title = {Morphological operators with discrete line segments}, optbooktitle = {Proc. of Discrete Geometry for Computer Imagery'2000, Uppsala}, pages = {78-98}, year = {2000}, opteditor = {Borgefors, G. and Nyström, I. and Sanniti di Baja, G.}, volume = {1953}, journal = {Lecture Notes in Computer Science}, doi = {10.1007/3-540-44438-6}, optpublisher = {Springer-Verlag} } @InProceedings{ koeppen-lohman-soille00, author = {Köppen, M. and Lohmann, L. and Soille, P.}, title = {N-dimensional Frameworks for the Application of Soft Computing to Image Processing}, editor = {Suzuki, Y. and Ovaska, S. and Furuhashi, T. and Roy, R. and Dote, Y.}, pages = {519-529}, booktitle = {Soft Computing in Industrial Applications}, year = {2000}, publisher = {Springer-Verlag} } @Article{ soille-misson2001, author = {Soille, P. and Misson, L.}, title = {Tree ring area measurements using morphological image analysis}, journal = {Canadian Journal of Forest Research}, year = {2001}, doi = {10.1139/cjfr-31-6-1074}, volume = {31}, number = {6}, pages = {1074-1083}, month = jun, url = {http://www.nrc.ca/cgi-bin/cisti/journals/rp/rp2_abst_e?cjfr_x01-025_31_ns_nf_cjfr6-01} } @Article{ whelan-soille-drimbarean2001, author = {Whelan, P. and Soille, P. and Drimbarean, A.}, title = {Real-time registration of paper watermarks}, journal = {Real-Time Imaging}, year = {2001}, volume = {7}, number = {4}, pages = {367-380}, doi = {10.1006/rtim.2000.0239}, month = aug } @Article{ soille-talbot2001, author = {Soille, P. and Talbot, H.}, title = {Directional morphological filtering}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {2001}, volume = {23}, number = {11}, pages = {1313-1329}, month = nov, doi = {10.1109/34.969120} } @Article{ soille2002pr, author = {Soille, P.}, title = {On morphological operators based on rank filters}, journal = {Pattern Recognition}, year = {2002}, volume = {35}, number = {2}, pages = {527-535}, doi = {10.1016/S0031-3203(01)00047-4}, month = feb } @Article{ ranwez-soille2002, author = {Ranwez, V. and Soille, P.}, title = {Order independent homotopic thinning for binary and grey tone anchored skeletons}, journal = {Pattern Recognition Letters}, year = {2002}, volume = {23}, number = {6}, pages = {687-702}, month = apr, doi = {10.1016/S0167-8655(01)00146-5} } @Article{ soille2002dgci, author = {Soille, P.}, title = {Advances in the analysis of topographic features on discrete images}, journal = {Lecture Notes in Computer Science}, year = {2002}, volume = {2301}, pages = {175-186}, month = mar, doi = {10.1007/3-540-45986-3} } @InProceedings{ vogt-etal2002dublin, author = {Vogt, J. and Colombo, R. and Paracchini, M. and Soille, P. and de Jager, A.}, title = {Development of a pan-{E}uropean database of rivers, lakes and catchments, in support to the needs of environmental policies}, booktitle = {{P}roceedings of the 8th EC-GI {\&} GIS Workshop, {ESDI}: {A} Work in Progress}, year = {2002}, location = {Dublin}, editor = {Fullerton, K. and Munro, A.}, publisher = {Joint Research Centre of the European Commission}, volume = {S.P.I.~02.102} } @Article{ soille-pesaresi2002, author = {Soille, P. and Pesaresi, M.}, title = {Advances in mathematical morphology applied to geoscience and remote sensing}, journal = {IEEE Transactions on Geoscience and Remote Sensing}, year = {2002}, volume = {40}, number = {9}, pages = {2042--2055}, month = sep, doi = {10.1109/TGRS.2002.804618} } @Article{ soille2002lnp, author = {Soille, P.}, title = {Morphological texture analysis: an introduction}, journal = {Lecture Notes in Physics}, year = {2002}, volume = {600}, pages = {215-237}, doi = {10.1007/3-540-45782-8_9} } @Book{ soille2003sv, author = {Soille, P.}, title = {Morphological Image Analysis: Principles and Applications}, psubtitle = {Principles and Applications}, edition = {2nd}, publisher = {Springer-Verlag}, doi = {10.1007/978-3-662-05088-0}, year = {2003}, psisbn = {3-540-42988-3}, address = {Berlin, Heidelberg, and New York}, purl = {http://www.springer.de/cgi/svcat/search_book.pl?isbn=3-540-42988-3} } @Book{ soille2003sverrata, author = {Soille, P.}, title = {Morphological Image Analysis: Principles and Applications}, psubtitle = {Principles and Applications}, edition = {2nd}, publisher = {Springer-Verlag}, year = {2003} } @InCollection{ vogt-etal2003, author = {Vogt, J. and Colombo, R. and Paracchini, M. and Soille, P. and de Jager, A. and Folving, S.}, title = {A {E}uropean landscape stratification reflecting drainage density}, booktitle = {Sustainable Development of Multifunctional Landscapes}, pages = {95-110}, publisher = {Springer-Verlag}, year = {2003}, editor = {Helming, K. and Wiggering, H.}, address = {Berlin, Heidelberg, and New York}, url = {http://www.springer.de/cgi/svcat/search_book.pl?isbn=3-540-00008-9} } @Article{ colombo-etal2003, author = {Colombo, R. and Vogt, J. and Soille, P. and Paracchini, M. and de Jager, A.}, title = {On the derivation of pan-{E}uropean river networks and catchment boundaries from a 250m {DEM}}, journal = {Geophysical Research Abstracts}, year = {2003}, volume = {5}, pages = {06474}, url = {http://www.cosis.net/abstracts/EAE03/06474/EAE03-J-06474.pdf} } @Book{ soillemd1-2003, editor = {Soille, P.}, title = {Morphology Digest, Vol. 10, Issue 1}, publisher = {Joint Research Centre of the European Commission}, month = mar, year = {2003}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest03-1/Digest03-1.html}, volume = {S.P/I.03.44} } @Book{ soillemd2-2003, editor = {Soille, P.}, title = {Morphology Digest, Vol. 10, Issue 2}, publisher = {Joint Research Centre of the European Commission}, month = jun, year = {2003}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest03-2/Digest03-2.html}, volume = {S.P/I.03.224} } @Book{ soillemd3-2003, editor = {Soille, P.}, title = {Morphology Digest, Vol. 10, Issue 3}, publisher = {Joint Research Centre of the European Commission}, month = jun, year = {2003}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest03-3/Digest03-3.html}, volume = {S.P/I.03.146} } @Book{ soillemd4-2003, editor = {Soille, P.}, title = {Morphology Digest, Vol. 10, Issue 4}, publisher = {Joint Research Centre of the European Commission}, month = dec, year = {2003}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest03-4/Digest03-4.html}, volume = {S.P/I.03.221} } @Book{ vogt-etal2003eur, author = {Vogt, J. and Colombo, R. and Paracchini, M. and de Jager, A. and Soille, P.}, title = {{CCM} {R}iver and Catchment Database, Version~1.0}, publisher = {Joint Research Centre of the European Commission}, year = {2003}, volume = {EUR~20756 EN}, url = {http://agrienv.jrc.it/activities/pdfs/CCM-Report-EUR20756EN.pdf} } @InProceedings{ epifanio-soille2003, author = {Epifanio, I. and Soille, P.}, title = {Segmentation of natural landscapes using morphological texture features}, booktitle = {Proceedings of IGARSS'03}, doi = {10.1109/IGARSS.2003.1293807}, pages = {455-457}, year = {2003}, volume = {I}, publisher = {IEEE Press} } @InProceedings{ paracchini-etal2003, author = {Paracchini, M. and Folving, S. and Vogt, J. and Colombo, R. and Soille, P.}, title = {Mapping and characterizing mountain catchments using {GIS} and earth observation data}, booktitle = {23th International Meeting of the Working Group on Mountain Watershed Management: Lessons Learned from the Past --- Lessons for the Future}, pages = {79-89}, year = {2003}, editor = {Greminger, P.}, volume = {165}, series = {Environmental Documentation}, address = {Berne}, publisher = {\htmladdnormallink{Swiss Agency for the Environment, Forests, and Landscape}{http://www.umwelt-schweiz.ch/buwal/}}, url = {http://gi-gis.jrc.it/publist/paracchini-etal2003.pdf} } @InProceedings{ bagli-soille2003, author = {Bagli, S. and Soille, P.}, title = {Morphological automatic extraction of coastline from pan-{E}uropean {L}andsat {TM} images}, booktitle = {Paper Proceedings of the Fifth International Symposium on GIS and Computer Cartography for Coastal Zone Management}, pages = {58-59}, year = {2003}, address = {Genova}, month = oct, publisher = {\htmladdnormallink{GISIG}{http://www.gisig.it/} and \htmladdnormallink{ICCOPS}{http://www.iccops.it}} } @InProceedings{ bagli-soille2003full, author = {Bagli, S. and Soille, P.}, title = {Morphological automatic extraction of coastline from pan-{E}uropean {L}andsat {TM} images}, booktitle = {Electronic Proceedings of the Fifth International Symposium on GIS and Computer Cartography for Coastal Zone Management}, year = {2003}, address = {Genova}, month = oct, publisher = {\htmladdnormallink{GISIG}{http://www.gisig.it/} and \htmladdnormallink{ICCOPS}{http://www.iccops.it}}, url = {http://www.ec-gis.org/sdi/publist/pdfs/bagli-soille2003.pdf} } @Article{ giada-etal2003cover, author = {Giada, S. and De Groeve, T. and Ehrlich, D. and Soille, P.}, title = {Can satellite images provide useful information on refugee camps?}, journal = {International Journal of Remote Sensing}, year = {2003}, volume = {24}, number = {22}, pages = {4249-4250}, month = nov, doi = {10.1080/014311601101107134} } @Article{ giada-etal2003, author = {Giada, S. and De Groeve, T. and Ehrlich, D. and Soille, P.}, title = {Information extraction from very high resolution satellite images over {L}ukole refugee camp, {T}anzania}, journal = {International Journal of Remote Sensing}, year = {2003}, volume = {24}, number = {22}, pages = {4251-4266}, month = nov, doi = {10.1080/0143116021000035021} } @Article{ soille2003dgci, author = {Soille, P.}, title = {On the morphological processing of objects with varying local contrast}, journal = {Lecture Notes in Computer Science}, year = {2003}, volume = {\htmladdnormallink{2886}{http://www.springerlink.com/openurl.asp?genre=issue&issn=0302-9743&volume=2886}}, pages = {52-61}, month = nov, optnote = {Proc. of DGCI'03, Uppsala, Sweden}, doi = {10.1007/b94107} } @Article{ soille-vogt-colombo2003wrr, author = {Soille, P. and Vogt, J. and Colombo, R.}, title = {Carving and adpative drainage enforcement of grid digital elevation models}, journal = {Water Resources Research}, year = {2003}, doi = {10.1029/2002WR001879}, volume = {39}, number = {12}, pages = {1366}, month = dec } @Book{ soille2004sverrata, author = {Soille, P.}, title = {Morphological Image Analysis: Principles and Applications}, psubtitle = {Principles and Applications}, edition = {corrected 2nd printing of the 2nd}, publisher = {Springer-Verlag}, doi = {10.1007/978-3-662-05088-0}, year = {2004}, psisbn = {3-540-42988-3}, address = {Berlin and New York}, purl = {http://www.springer.de/cgi/svcat/search_book.pl?isbn=3-540-42988-3} } @Book{ soille2004sv, author = {Soille, P.}, title = {Morphological Image Analysis: Principles and Applications}, psubtitle = {Principles and Applications}, edition = {corrected 2nd printing of the 2nd}, publisher = {Springer-Verlag}, doi = {10.1007/978-3-662-05088-0}, year = {2004}, psisbn = {3-540-42988-3}, address = {Berlin and New York}, purl = {http://www.springer.de/cgi/svcat/search_book.pl?isbn=3-540-42988-3} } @Book{ soille2004sv_short, author = {Soille, P.}, title = {Morphological Image Analysis: Principles and Applications}, psubtitle = {Principles and Applications}, edition = {2nd}, publisher = {Springer-Verlag}, doi = {10.1007/978-3-662-05088-0}, year = {2004}, psisbn = {3-540-42988-3}, address = {Berlin and New York}, purl = {http://www.springer.de/cgi/svcat/search_book.pl?isbn=3-540-42988-3} } @Article{ soille2004prl, author = {Soille, P.}, title = {Morphological Carving}, journal = {Pattern Recognition Letters}, year = {2004}, volume = {25}, number = {5}, pages = {543-550}, month = apr, doi = {10.1016/j.patrec.2003.12.007} } @Book{ soillemd1-2004, editor = {Soille, P.}, title = {Morphology Digest, Vol. 11, Issue 1}, publisher = {Joint Research Centre of the European Commission}, month = mar, year = {2004}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest04-1/Digest04-1.html}, volume = {S.P/I.04.47} } @Book{ soillemd2-2004, editor = {Soille, P.}, title = {Morphology Digest, Vol. 11, Issue 2}, publisher = {Joint Research Centre of the European Commission}, month = may, year = {2004}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest04-2/Digest04-2.html}, volume = {S.P/I.04.99} } @Book{ soillemd3-2004, editor = {Soille, P.}, title = {Morphology Digest, Vol. 11, Issue 3}, publisher = {Joint Research Centre of the European Commission}, month = oct, year = {2004}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest04-3/Digest04-3.html}, volume = {S.P/I.04.184} } @InCollection{ maggi-etal2004, author = {Maggi, M. and Soille, P. and Estreguil, C. and Deshayes, M.}, title = {Detection of vegetation changes in an alpine protected area}, booktitle = {Analysis of multi-temporal remote sensing images}, editor = {Smits, P. and Bruzzone, L.}, publisher = {World scientific}, year = {2004}, volume = {3}, doi = {10.1142/9789812702630_0028}, pages = {249--258}, series = {Series in remote sensing}, address = {Singapore} } @InProceedings{ masson-soille-mueller2004, author = {Masson, J. and Soille, P. and Mueller, R.}, title = {Tests with {VHR} images for the identification of olive trees and other fruit trees in the {E}uropean {U}nion}, booktitle = {Proc. of Remote Sensing for Agriculture, Ecosystems, and Hydrology VI}, pages = {23-36}, year = {2004}, editor = {Owe, M. and D'Urso, G.}, volume = {5568}, publisher = {Society of Photo-Instrumentation Engineers}, address = {Bellingham}, doi = {10.1117/12.562439}, month = sep } @Unpublished{ bagli-soille2004, author = {Bagli, S. and Soille, P.}, title = {From morphological image analysis to pan-{E}uropean layers}, month = {13th--19th May}, year = {2004} } @InProceedings{ bagli-soille2004eco-imagine, author = {Bagli, S. and Soille, P.}, title = {Automatic delineation of shoreline and lake boundaries from Landsat satellite images}, url = {http://www.ec-gis.org/sdi/publist/pdfs/bagli-soille2004.pdf}, booktitle = {Proc. of ECO-IMAGINE conference GI and GIS for Integrated Coastal Management, Sevilla, Spain}, month = may, year = {2004} } @Article{ soille2004wrr, author = {Soille, P.}, title = {Optimal removal of spurious pits in grid digital elevation models}, journal = {Water Resources Research}, year = {2004}, doi = {10.1029/2004WR003060}, volume = {40}, number = {12}, pages = {W12509}, month = dec } @InProceedings{ paracchini-etal2004, author = {Paracchini, M. and Vogt, J. and Soille, P. and de Jager, A. and Colombo, R.}, title = {Development of a pan-{E}uropean database of rivers and catchments: a {GIS} application in support to {E}uropean water monitoring activities}, booktitle = {Proc. of Workshop on Identification of the current status and needs of GIS and databases technology in the agricultural sector sector - GIS for analysis and monitoring of land use and land/water quality}, pages = {VI.1--VI.10}, year = {2004}, editor = {Stuczynski, T.}, month = {4 - 6 March 2004, Pulawy/ Poland}, url = {http://www.proland.iung.pulawy.pl/materials/wp1/paracchini.pdf} } @Article{ soille2005ivc, author = {Soille, P.}, title = {Beyond self-duality in morphological image analysis}, journal = {Image and Vision Computing}, year = {2005}, doi = {10.1016/j.imavis.2004.06.002}, volume = {23}, number = {2}, pages = {249-257}, month = feb } @InCollection{ brunner-soille2005, author = {Brunner, D. and Soille, P.}, title = {Iterative area seeded region growing for multichannel image simplification}, booktitle = {Mathematical Morphology: 40 Years On}, pages = {397-406}, doi = {10.1007/1-4020-3443-1_36}, publisher = {Springer-Verlag}, year = {2005}, editor = {Ronse, C. and Najman, L. and Decencière, E.}, volume = {30}, series = {Computational Imaging and Vision}, address = {Dordrecht} } @Article{ iwanowski-soille2005caip1, author = {Iwanowski, M. and Soille, P.}, title = {A queue based algorithm for order independent anchored skeletonisation}, journal = {Lecture Notes in Computer Science}, year = {2005}, month = sep, volume = {3691}, pages = {530-537}, doi = {10.1007/11556121_65} } @Article{ iwanowski-soille2005caip2, author = {Iwanowski, M. and Soille, P.}, title = {Morphological refinement of an image segmentation}, journal = {Lecture Notes in Computer Science}, year = {2005}, month = sep, volume = {3691}, pages = {538-545}, doi = {10.1007/11556121_66} } @Article{ bielski-soille2005iciap, author = {Bielski, C. and Soille, P.}, title = {Order independent image compositing}, journal = {Lecture Notes in Computer Science}, year = {2005}, month = sep, volume = {3617}, pages = {1076-1083}, doi = {10.1007/11553595_132} } @Article{ soille2006pami, author = {Soille, P.}, title = {Morphological image compositing}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {2006}, volume = {28}, number = {5}, pages = {673-683}, month = may, doi = {10.1109/TPAMI.2006.99} } @Article{ iwanowski-soille2006, author = {Iwanowski, M. and Soille, P.}, title = {Order independence in binary 2{D} homotopic thinning}, journal = {Lecture Notes in Computer Science}, year = {2006}, doi = {10.1007/11907350}, volume = {4245}, pages = {592-604}, month = oct } @InCollection{ bielski-soille2006endmembers, author = {Bielski, C. and Soille, P.}, title = {A mathematical morphology based approach to locating spectral endmembers}, booktitle = {Imaging Spectroscopy: New quality in environmental studies}, pages = {545-552}, publisher = {Wydawnictwa Przemyslowe WEMA Sp z.o.o.}, year = {2006}, editor = {Zagajewski, B. and Sobczak, M.}, address = {Warszawa}, isbn = {83-89502-41-0} } @TechReport{ soille2006tr, author = {Soille, P.}, title = {On range based connectivity relations for image simplification and segmentation}, institution = {Joint Research Centre of the European Commission}, year = {2006} } @Article{ vogt-etal2007ei, author = {Vogt, P. and Riitters, K. and Iwanowski, M. and Estreguil, C. and Kozak, J. and Soille, P.}, title = {Mapping landscape corridors}, journal = {Ecological Indicators}, year = {2007}, doi = {10.1016/j.ecolind.2006.11.001}, volume = {7}, number = {2}, pages = {481-488}, month = apr } @Article{ maggi-estreguil-soille2007, author = {Maggi, M. and Estreguil, C. and Soille, P.}, title = {Woody vegetation increases in {A}lpine areas: a proposal for a classification and validation scheme}, journal = {International Journal of Remote Sensing}, year = {2007}, doi = {10.1080/01431160600851785}, volume = {28}, number = {1}, pages = {143-166}, month = jan } @Article{ epifanio-soille2007, author = {Epifanio, I. and Soille, P.}, title = {Morphological texture features for unsupervised and supervised segmentations of natural landscapes}, journal = {IEEE Transactions on Geoscience and Remote Sensing}, year = {2007}, doi = {10.1109/TGRS.2006.890581}, volume = {45}, number = {4}, pages = {1074-1083}, month = apr } @Article{ riitters-etal2007le, author = {Riitters, K. and Vogt, P. and Soille, P. and Kozak, J. and Estreguil, C.}, title = {Neutral model analysis of landscape patterns from mathematical morphology}, journal = {Landscape Ecology}, year = {2007}, doi = {10.1007/s10980-007-9089-3}, volume = {22}, number = {7}, pages = {1033-1043}, month = aug } @Article{ iwanowski-soille2007icannga, author = {Iwanowski, M. and Soille, P.}, title = {Fast algorithms for order independent binary homotopic thinning}, journal = {Lecture Notes in Computer Science}, year = {2007}, doi = {10.1007/978-3-540-71629-7_68}, volume = {4432}, number = {2}, pages = {606-615}, month = apr } @Article{ bielski-soille2007icannga, author = {Bielski, C. and Soille, P.}, title = {Adaptive mosaicing: principle and application to the mosaicing of large image data sets}, journal = {Lecture Notes in Computer Science}, year = {2007}, doi = {10.1007/978-3-540-71629-7_56}, volume = {4432}, number = {2}, pages = {500-507}, month = apr } @Article{ brunner-soille2007, author = {Brunner, D. and Soille, P.}, title = {Iterative area filtering of multichannel images}, journal = {Image and Vision Computing}, year = {2007}, doi = {10.1016/j.imavis.2006.09.002}, volume = {25}, number = {8}, pages = {1352-1364}, month = aug } @InCollection{ soille2007dem, author = {Soille, P.}, title = {From mathematical morphology to morphological terrain features}, booktitle = {Digital Terrain Modelling}, subtitle = {Development and Applications in a Policy Support Environment}, doi = {10.1007/978-3-540-36731-4_2}, pages = {45-66}, publisher = {Springer-Verlag}, year = {2007}, editor = {Peckham, R. and Jordan, G.}, optseries = {Lecture Notes in Geoinformation and Cartography}, address = {Berlin} } @InCollection{ vogt-etal2007dem, author = {Vogt, J. and Soille, P. and Colombo, R. and Paracchini, M. and de Jager, A.}, title = {Development of a pan-{E}uropean river and catchment database}, booktitle = {Digital Terrain Modelling}, subtitle = {Development and Applications in a Policy Support Environment}, pages = {121-144}, publisher = {Springer-Verlag}, year = {2007}, editor = {Peckham, R. and Jordan, G.}, optseries = {Lecture Notes in Geoinformation and Cartography}, month = aug, doi = {10.1007/978-3-540-36731-4_6} } @Article{ grazzini-soille2007caip, author = {Grazzini, J. and Soille, P.}, title = {Improved morphological interpolation of elevation contour data with generalised geodesic propagations}, journal = {Lecture Notes in Computer Science}, year = {2007}, doi = {10.1007/978-3-540-74272-2_92}, volume = {4673}, pages = {742-750} } @Article{ soille-grazzini2007caip, author = {Soille, P. and Grazzini, J.}, title = {Extraction of river networks from satellite images by combining mathematical morphology and hydrology}, journal = {Lecture Notes in Computer Science}, year = {2007}, doi = {10.1007/978-3-540-74272-2_79}, volume = {4673}, pages = {636-644}, month = aug } @Article{ colombo-etal2007catena, author = {Colombo, R. and Vogt, J. and Soille, P. and Paracchini, M. and de Jager, A.}, title = {On the derivation of river networks and catchments at {E}uropean scale from medium resolution digital elevation data}, journal = {Catena}, year = {2007}, doi = {10.1016/j.catena.2006.10.001}, volume = {70}, number = {3}, pages = {296-305}, month = aug } @Book{ vogt-etal2007ref, author = {Vogt, J. and Soille, P. and de Jager, A. and Rimavi\v{c}i\={u}te, E. and Mehl, S. and Foisneau, S. and B\'odis, K. and Dusart, J. and Paracchini, M. and Haastrup, P. and Bamps. C.}, title = {A Pan-{E}uropean River and Catchment Database}, publisher = {European Publications Office}, year = {2007}, doi = {10.2788/35907}, volume = {EUR~22920~EN}, obsurl = {http://agrienv.jrc.it/publications/pdfs/CCM2-Report_EUR-22920-EN_2007_STD.pdf} } @InProceedings{ soille2007iciap, author = {Soille, P.}, title = {On genuine connectivity relations based on logical predicates}, doi = {10.1109/ICIAP.2007.4362825}, booktitle = {Proc. of 14th Int. Conf. on Image Analysis and Processing, Modena, Italy}, pages = {487-492}, year = {2007}, month = sep, publisher = {IEEE Computer Society Press} } @InProceedings{ soille2007iciapshort, author = {Soille, P.}, title = {On genuine connectivity relations based on logical predicates}, doi = {10.1109/ICIAP.2007.4362825}, booktitle = {Proc. of 14th ICIAP, Modena, Italy}, pages = {487-492}, year = {2007}, month = sep, publisher = {IEEE} } @InProceedings{ bielski-etal2007igarss, author = {Bielski, C. and J. Grazzini and P. Soille}, title = {Automated morphological image composition for mosaicing large image data sets}, booktitle = {Proc. Int. Geosc. and Rem. Sens. Symp.}, pages = {4068-4071}, year = {2008}, doi = {10.1109/IGARSS.2007.4423743}, address = {Barcelona}, month = jul, publisher = {IEEE Press} } @InProceedings{ grazzini-soille2008visapp, author = {Grazzini, J. and Soille, P.}, title = {Edge-preserving smoothing of natural images based on geodesic time functions}, booktitle = {Proc. of International Conference on Computer Vision Theory and Applications (VISAPP'08)}, doi = {10.5220/0001087400200027}, pages = {20-27}, year = {2008}, editor = {Ranchordas, A. and Ara\'ujo, H.}, volume = {1}, address = {Madeira, Portugal}, month = jan, publisher = {INSTICC Press, Portugal} } @Article{ soille-grazzini2008dgci, author = {Soille, P. and Grazzini, J.}, title = {Advances in constrained connectivity}, journal = {Lecture Notes in Computer Science}, year = {2008}, doi = {10.1007/978-3-540-79126-3_38}, volume = {4992}, pages = {423-433}, month = apr } @InProceedings{ soille-grazzini2008dgci_inproc, author = {Soille, P. and Grazzini, J.}, title = {Advances in constrained connectivity}, doi = {10.1007/978-3-540-79126-3_38}, longbooktitle = {Proc. of DGCI'08, Lyon}, booktitle = {Proc. of DGCI'08, Lyon}, pages = {423-433}, year = {2008}, editor = {Coeurjolly, D. and Sivignon, I. and Tougne, L. and Dupond, F.}, volume = {4992}, series = {Lecture Notes in Computer Science}, month = apr } @Article{ grazzini-soille2008dgci, author = {Grazzini, J. and Soille, P.}, title = {Adaptive morphological filtering using similarities based on geodesic time}, doi = {10.1007/978-3-540-79126-3_46}, journal = {Lecture Notes in Computer Science}, year = {2008}, volume = {4992}, pages = {519-528}, month = apr } @InProceedings{ grazzini-soille2008dgci_inproc, author = {Grazzini, J. and Soille, P.}, title = {Adaptive morphological filtering using similarities based on geodesic time}, doi = {10.1007/978-3-540-79126-3_46}, booktitle = {Proc. of DGCI'08, Lyon}, editor = {Coeurjolly, D. and Sivignon, I. and Tougne, L. and Dupond, F.}, series = {Lecture Notes in Computer Science}, year = {2008}, volume = {4992}, pages = {519-528}, month = apr } @Article{ soille2008pamierrata, author = {Soille, P.}, title = {Constrained connectivity for hierarchical image partitioning and simplification}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {2008}, doi = {10.1109/TPAMI.2007.70817}, volume = {30}, number = {7}, pages = {1132-1145}, month = jul, optnote = {[Available as online preprint since 18 October 2007]}, pubsy-id = {JRC36392} } @Article{ soille2008pami, author = {Soille, P.}, title = {Constrained connectivity for hierarchical image partitioning and simplification}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {2008}, doi = {10.1109/TPAMI.2007.70817}, volume = {30}, number = {7}, pages = {1132-1145}, month = jul, optnote = {[Available as online preprint since 18 October 2007]}, pubsy-id = {JRC36392} } @InProceedings{ strobl-etal2008earsel2007, author = {Strobl, P. and Reithmaier, L. and Soille, P. and Mehl, W. and Bielski, C.}, title = {Assembly of a remotely sensed reference image of {E}urope at 25m resolution}, url = {http://www.ec-gis.org/sdi/publist/pdfs/strobl-etal2008earsel2007.pdf}, booktitle = {Geoinformation in Europe}, pages = {515-522}, year = {2008}, editor = {Gomarasca, M.}, address = {Rotterdam, Netherlands}, action = {cosin}, publisher = {Millpress} } @InCollection{ reuter-etal2008geomorph, author = {Reuter, H. and Hengl, T. and Gessler, P. and Soille, P.}, title = {Preparation of {DEM}s for geomorphometric analysis}, booktitle = {Geomorphometry: Concepts, Software, and Applications}, pages = {87-120}, publisher = {Elsevier}, year = {2008}, editor = {Hengl, T. and Reuter, H.}, optvolume = {33}, optseries = {Developments in Soil Science}, chapter = {4}, doi = {10.1016/S0166-2481(08)00004-4} } @InProceedings{ poggio-soille2008eurosoil, author = {Poggio, L. and Soille, P.}, title = {{DEM} quality indicators for the derivation of geomorphological parameters}, booktitle = {EUROSOIL 2008: Book of Abstracts}, pages = {142}, year = {2008}, editor = {Blum, W. and Gerzabek, M. and Vodrazka, M.}, address = {Vienna, Austria}, publisher = {University of Natural Resources and Applied Life Sciences (BOKU)}, url = {http://www.ecsss.net/web/MDB/media_folder/39_abstracts.pdf} } @Book{ soillemd1-2008, editor = {Soille, P.}, title = {Morphology Digest, Vol. 15, Issue 1}, publisher = {Joint Research Centre of the European Commission}, month = jul, year = {2008}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest08-1} } @Book{ soillemd2-2008, editor = {Soille, P.}, title = {Morphology Digest, Vol. 15, Issue 2}, publisher = {Joint Research Centre of the European Commission}, month = dec, year = {2008}, url = {http://p.soille.free.fr/mdigest/DIGEST/Digest08-2} } @Book{ poggio-soille2008eur, author = {Poggio, L. and Soille, P.}, title = {Quality Assessment of Hydrogeomorphological Features Derived from Digital Terrain Models}, publisher = {Joint Research Centre of the European Commission}, year = {2008}, doi = {10.2788/61787}, series = {JRC Scientific and Technical Reports}, number = {EUR~23489~EN} } @Book{ soille2008image2k6, editor = {Soille, P.}, title = {The {IMAGE-2006} Mosaic Project}, publisher = {Joint Research Centre of the European Commission}, year = {2008}, doi = {10.2788/25572} } @Book{ soille2008dmc, author = {Soille, P.}, title = {{DMC-2007} Mosaic: Data Ingestion and Organisation}, publisher = {Joint Research Centre of the European Commission}, year = {2008}, doi = {10.2788/49274} } @Book{ soille2008i2k6_clouds, author = {Soille, P.}, title = {IMAGE-2006 Mosaic: SPOT-4 HRVIR, SPOT-5 HRG, and IRS-LISS III Cloud Detection}, publisher = {Joint Research Centre of the European Commission}, year = {2008}, doi = {10.2788/49355} } @Book{ soille-bielski2011i2k6_seam, author = {Soille, P.}, title = {IMAGE-2006 Mosaic: Automatic Seam Line Delineation}, publisher = {Joint Research Centre of the European Commission}, year = {2011}, doi = {10.2788/50299} } @Book{ soille-grazzini2011i2k6_consistency, author = {Soille, P.}, title = {IMAGE-2006 Mosaic: Geometric and Radiometric Consistency of Input Imagery}, publisher = {Joint Research Centre of the European Commission}, year = {2011}, doi = {10.2788/50967} } @InCollection{ grazzini-soille2009ccis, author = {Grazzini, J. and Soille, P.}, title = {Image filtering based on locally estimated geodesic functions}, booktitle = {Computer Vision and Computer Graphics: Theory and Practice}, pages = {123-134}, publisher = {Springer-Verlag}, year = {2009}, doi = {10.1007/978-3-642-10226-4_10}, editor = {Ranchordas, A. and Araujo, H. and Madeiras Pereira, J. and Braz, J.}, volume = {24}, series = {Communications in Computer and Information Science} } @Article{ soille-vogt2009, author = {Soille, P. and Vogt, P.}, title = {Morphological segmentation of binary patterns}, journal = {Pattern Recognition Letters}, year = {2009}, doi = {10.1016/j.patrec.2008.10.015}, volume = {30}, number = {4}, pages = {456-459}, month = mar } @Article{ riitters-etal2009, author = {Riitters, K. and Vogt, P. and Soille, P. and Estreguil, C.}, title = {Landscape patterns from mathematical morphology on maps with contagion}, journal = {Landscape Ecology}, year = {2009}, doi = {10.1007/s10980-009-9344-x}, volume = {24}, number = {5}, pages = {699-709}, month = may } @Article{ grazzini-soille2009, author = {Grazzini, J. and Soille, P.}, title = {Edge-preserving smoothing using a similarity measure in adaptive geodesic neighbourhoods}, journal = {Pattern Recognition}, year = {2009}, doi = {10.1016/j.patcog.2008.11.004}, volume = {42}, number = {10}, pages = {2306-2316}, month = oct } @InProceedings{ brunner-soille2009, author = {Brunner, D. and Soille, P.}, title = {Towards building shadow extraction in {VHR} {SAR} images using mathematical morphology}, url = {http://www.cs.rug.nl/~ISMM09/ISMMabstractbook.pdf}, booktitle = {Abstract book of the 9th Int. Symp on Math. Morph (ISMM'2009)}, pages = {17-20}, year = {2009}, editor = {M. Wilkinson and J. Roerdink}, address = {The Netherlands}, publisher = {University of Groningen} } @InProceedings{ poggio-soille2009ifcs, author = {Poggio, L. and Soille, P.}, title = {Land cover classification with unsupervised clustering and hierarchical partitioning}, url = {http://www.ifcs2009.de/pdf/abstracts_0-03.pdf}, booktitle = {11th Int. Conf. of the International Federation of Classification Societies (IFCS): Classification as a Tool for Research}, year = {2009}, address = {Dresden, Germany}, editor = {Esswein, W. and Hilbert, A. and Locarek-Junge, H.}, publisher = {TU Dresden}, pages = {171-172}, month = mar } @InProceedings{ poggio-soille2009geomorphometry, author = {Poggio, L. and Soille, P.}, title = {Influence of spurious pit removal methods on the position of river networks extracted from {SRTM}}, url = {http://geomorphometry.org/system/files/poggio2009geomorphometry.pdf}, booktitle = {Proc. of Geomorphometry 2009}, pages = {231-236}, year = {2009}, editor = {Purves, R. and Gruber, S. and Hengl, T. and Straumann}, address = {Z{\"u}rich}, month = sep, publisher = {University of Z{\"u}rich} } @Article{ soille-grazzini2009ismm, author = {Soille, P. and Grazzini, J.}, title = {Constrained connectivity and transition regions}, journal = {Lecture Notes in Computer Science}, year = {2009}, doi = {10.1007/978-3-642-03613-2_6}, volume = {5720}, pages = {59-69} } @InProceedings{ soille-grazzini2009ismm_inproc, author = {Soille, P. and Grazzini, J.}, title = {Constrained connectivity and transition regions}, doi = {10.1007/978-3-642-03613-2_6}, booktitle = {Proc. of 9th Int. Symp. on Mathematical Morphology}, pages = {59-69}, year = {2009}, volume = {5720}, series = {Lecture Notes in Computer Science}, optmonth = aug, optorganization={University of Groningen}, optpublisher = {Springer-Verlag}, optaddress = {Berlin} } @InProceedings{ soille-grazzini2009ismm_inproced, author = {Soille, P. and Grazzini, J.}, title = {Constrained connectivity and transition regions}, doi = {10.1007/978-3-642-03613-2_6}, booktitle = {Proc. of 9th Int. Symp. on Mathematical Morphology}, pages = {59-69}, year = {2009}, editor = {Wilkinson, M. and Roerdink, J.}, volume = {5720}, series = {Lecture Notes in Computer Science}, optmonth = aug, optorganization={University of Groningen}, optpublisher = {Springer-Verlag}, optaddress = {Berlin} } @InProceedings{ soille2009spie, author = {Soille, P.}, title = {Recent developments in morphological image processing for remote sensing}, doi = {10.1117/12.836024}, booktitle = {Image and Signal Processing for Remote Sensing}, year = {2009}, editor = {Bruzzone, L. and Benediktsson, J. and Serpico, S.}, volume = {SPIE-7477}, publisher = {SPIE} } @InProceedings{ kemper-jenerowicz-soille2009valgeo, author = {Kemper, T. and Jenerowicz, M. and Soille, P.}, title = {Counting people in refugees/{IDP} camps in {D}arfur/{S}udan: what error is acceptable?}, doi = {10.2788/46126}, booktitle = {Proc. of Int. Workshop on VALidation of Geo-information Products for Crisis Management (VALgEO'2009)}, pages = {153-155}, year = {2009}, editor = {Corbane, C. and Broglia, M. and Carrion, D. and Lemoine, G. and Pesaresi, M.}, number = {EUR~24082~EN}, month = nov, publisher = {Joint Research Centre of the European Commission} } @InProceedings{ gueguen-etal2009, author = {Gueguen, L. and Pesaresi, M. and Soille, P. and Gerhardinger, A.}, title = {Morphological descriptors and spatial aggregations for characterizing damaged buildings in very high resolution images}, url = {http://earth.eo.esa.int/rtd/Events/2009_ESA-EUSC-JRC/Papers/Pap_Gueguen.pdf}, booktitle = {Proc. of 6th Conference on Image Information Mining}, year = {2009}, editor = {Datcu, M.}, month = nov, organization = {ESA-EUSC-JRC}, publisher = {European Space Agency} } @Article{ jenerowicz-etal2010rit, author = {Jenerowicz, M. and Kemper, T. and Pesaresi, M. and Soille, P.}, title = {Post-event damage assessment using morphological methodology on 0.5m resolution satellite data}, journal = {Rivista Italiana di Telerilevamento}, year = {2010}, volume = {42}, number = {3}, pages = {37-47}, url = {http://www.aitjournal.com/articleView.aspx?ID=185} } @Article{ jenerowicz-etal2010itjrs, author = {Jenerowicz, M. and Kemper, T. and Pesaresi, M. and Soille, P.}, title = {Post-event damage assessment using morphological methodology on 0.5m resolution satellite data}, journal = {Italian Journal of Remote Sensing}, year = {2010}, volume = {42}, number = {3}, pages = {37-47}, url = {http://www.aitjournal.com/articleView.aspx?ID=185} } @InCollection{ soille2010mm, author = {Soille, P.}, title = {Images Satellites et Modèles Numériques de Terrain}, booktitle = {Morphologie Mathématique}, pages = {215-227}, publisher = {Hermès}, year = {2010}, editor = {Talbot, H. and Najman, L.}, volume = {2}, chapter = {IV.5}, address = {Paris} } @InCollection{ soille2010satdem, author = {Soille, P.}, title = {Satellite imagery and digital elevation models}, booktitle = {Mathematical Morphology}, pages = {393-405}, publisher = {ISTE {\&} Wiley}, year = {2010}, doi = {10.1002/9781118600788.ch17}, editor = {Najman, L. and Talbot, H.} } @Book{ koethe-montanvert-soille2010, title = {Proc. of ICPR Workshop on Applications of Discrete Geometry and Mathematical Morphology}, year = {2010}, editor = {K\"othe, U. and Montanvert, A. and Soille, P.}, address = {Istanbul}, month = aug, publisher = {IAPR} } @InProceedings{ najman-soille2010wadgmm, author = {Najman, L. and Soille, P.}, title = {On morphological hierarchical representations for image processing and spatial data clustering}, booktitle = {Proc. of ICPR Workshop on Applications of Discrete Geometry and Mathematical Morphology}, pages = {52-61}, year = {2010}, editor = {K\"othe, U. and Montanvert, A. and Soille, P.}, address = {Istanbul}, month = aug, publisher = {IAPR} } @InProceedings{ najman-soille2010wadgmmshort, author = {Najman, L. and Soille, P.}, title = {On morphological hierarchical representations for image processing and spatial data clustering}, booktitle = {Proc. of WADGMM ICPR Workshop}, pages = {52-61}, year = {2010}, opteditor = {K\"othe, U. and Montanvert, A. and Soille, P.}, address = {Istanbul}, month = aug, publisher = {IAPR}, optnote = {[Invited paper]} } @InProceedings{ wilkinson-soille-2010wadgmmshort, author = {Wilkinson, M. and Soille, P. and Ouzounis, G. }, title = {Concurrent computation of differential morphological profiles for remote sensing}, booktitle = {Proc. of WADGMM ICPR Workshop}, pages = {67-71}, year = {2010}, opteditor = {K\"othe, U. and Montanvert, A. and Soille, P.}, address = {Istanbul}, month = aug, publisher = {IAPR} } @InCollection{ poggio-soille2010sv, author = {Poggio, L. and Soille, P.}, title = {Land cover detection with unsupervised clustering and hierarchical partitioning}, booktitle = {Classification as a Tool for Research}, optisbn = {978-3-642-10744-3}, doi = {10.1007/978-3-642-10745-0_49}, publisher = {Springer-Verlag}, year = {2010}, pages = {455-462}, editor = {Locarek-Junge, H. and Weihs, C.}, series = {Studies in Classification, Data Analysis, and Knowledge Organization} } @InProceedings{ grazzini-soille2010icpr, author = {Grazzini, J. and Soille, P.}, title = {Iterative ramp sharpening for structure/signature-preserving simplification of images}, doi = {10.1109/ICPR.2010.1120}, pages = {4585-4589}, booktitle = {Proc. of 20th Int. Conf. on Pattern Recognition}, year = {2010}, address = {Istanbul}, month = aug, publisher = {IEEE} } @InProceedings{ grazzini-dillard-soille2010icpr, author = {Grazzini, J. and Dillard, S. and Soille, P.}, title = {Multichannel image regularisation using anisotropic geodesic filtering}, doi = {10.1109/ICPR.2010.653}, booktitle = {Proc. of 20th Int. Conf. on Pattern Recognition}, pages = {2664-2667}, year = {2010}, address = {Istanbul}, month = aug, publisher = {IEEE} } @InProceedings{ ouzounis-soille2010icpr, author = {Ouzounis, G. and Soille, P.}, title = {Differential area profiles}, doi = {10.1109/ICPR.2010.993}, booktitle = {Proc. of 20th Int. Conf. on Pattern Recognition}, pages = {4085-4088}, year = {2010}, address = {Istanbul}, month = aug, publisher = {IEEE} } @InProceedings{ akcay-aksoy-soille2010icpr, author = {Akçay, G. and Aksoy, S. and Soille, P.}, title = {Hierarchical segmentation of complex structures}, doi = {10.1109/ICPR.2010.280}, booktitle = {Proc. of 20th Int. Conf. on Pattern Recognition}, pages = {1120-1123}, year = {2010}, address = {Istanbul}, month = aug, publisher = {IEEE} } @InProceedings{ gueguen-soille-pesaresi2010icpr, author = {Gueguen, L. and Soille, P. and Pesaresi, M.}, title = {Differential morphological decomposition segmentation: a multi-scale object based image description}, doi = {10.1109/ICPR.2010.235}, booktitle = {Proc. of 20th Int. Conf. on Pattern Recognition}, pages = {938-941}, year = {2010}, address = {Istanbul}, month = aug, publisher = {IEEE} } @InProceedings{ poggio-soille2010accuracy_abstract, author = {Poggio, L. and Soille, P.}, title = {Modelling uncertainty in watershed divides from {SRTM} and {GDEM}}, booktitle = {Delegate Handbook of Accuracy'2010 Symposium}, pages = {109}, year = {2010}, address = {Leicester, U.K.} } @InProceedings{ poggio-soille2010accuracy, author = {Poggio, L. and Soille, P.}, title = {Modelling uncertainty in watershed divides from {SRTM} and {GDEM}}, booktitle = {Proc. of the 9th Int. Symp. on Spatial Accuracy Assessment in Natural Resources and Environmental Sciences}, pages = {417-419}, editor = {Tate, N. and Fisher, P.}, year = {2010}, address = {Leicester, U.K.}, publisher = {International Spatial Accuracy Research Association}, url = {http://www.spatial-accuracy.org/system/files/img-X07133653_0.pdf} } @InProceedings{ pesaresi-etal2010igarss, author = {Pesaresi, M. and Kemper, T. and Gueguen, L. and Soille, P.}, title = {Automatic information retrieval from meter and sub-meter resolution satellite image data in support to crisis management}, booktitle = {Proc. Int. Geosc. and Rem. Sens. Symp.}, pages = {1792-1795}, year = {2010}, doi = {10.1109/IGARSS.2010.5653039}, address = {Honolulu}, month = jul, publisher = {IEEE Press} } @Article{ soille2010ijrs, author = {Soille, P.}, title = {Constrained connectivity for the processing of very high resolution satellite images}, journal = {International Journal of Remote Sensing}, year = {2010}, doi = {10.1080/01431161.2010.512622}, volume = {31}, number = {22}, pages = {5879-5893}, month = jul } @InProceedings{ grazzini-dillard-soille2010spie, author = {Grazzini, J. and Dillard, S. and Soille, P.}, title = {A new generic method for semi-automatic extraction of rivers and road networks in low- and mid-resolution satellite images}, doi = {10.1117/12.865052}, page = {783007}, booktitle = {Proc. of Image and Signal Processing for Remote Sensing XVI}, volume = {SPIE 7830}, year = {2010} } @Proceedings{ soille-etal2011iimproc, title = {Proc. of the 7th ESA-EUSC-JRC Conference on Image Information Mining}, year = {2011}, doi = {10.2788/69291}, editor = {Soille, P. and Gueguen, L. and D'Elia, S. and Marchetti, P.G. and Colaiacomo, L. and Datcu, M.}, publisher = {Joint Research Centre of the European Commission}, month = mar } @InProceedings{ gueguen-soille-pesaresi2011iim, author = {Gueguen, L. and Soille, P. and Pesaresi, M.}, title = {Structure extraction and characterization from differential morphological decomposition}, doi = {10.2788/69291}, booktitle = {Proc. of the 7th ESA-EUSC-JRC Conference on Image Information Mining}, pages = {53-57}, editor = {Soille, P. and Gueguen, L. and D'Elia, S. and Marchetti, P.G. and Colaiacomo, L. and Datcu, M.}, publisher = {Joint Research Centre of the European Commission}, year = {2011} } @Article{ kemper-etal2011jstar, author = {Kemper, T. and Jenerowicz, M. and Pesaresi, M. and Soille, P.}, title = {Enumeration of dwellings in {D}arfur camps from {G}eo{E}eye-1 satellite images using mathematical morphology}, journal = {IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing}, year = {2011}, doi = {10.1109/JSTARS.2010.2053700}, volume = {4}, number = {1}, pages = {8-15}, month = mar } @Proceedings{ soille-pesaresi-ouzounis2011ismm, title = {Mathematical Morphology and Its Applications to Image and Signal Processing: Proc. of 10th Int. Symp, ISMM 2011}, year = {2011}, editor = {Soille, P. and Pesaresi, M. and Ouzounis, G.}, volume = {6671}, series = {Lecture Notes in Computer Science}, doi = {10.1007/978-3-642-21569-8}, publisher = {Springer-Verlag} } @Article{ soille2011ismm, author = {Soille, P.}, title = {Preventing chaining through transitions while favouring it within homogeneous regions}, doi = {10.1007/978-3-642-21569-8_9}, journal = {Lecture Notes in Computer Science}, pages = {96--107}, year = {2011}, volume = {6671} } @Article{ gueguen-soille2011ismm, author = {Gueguen, L. and Soille, P.}, title = {Frequent and dependent connectivities}, doi = {10.1007/978-3-642-21569-8_11}, journal = {Lecture Notes in Computer Science}, pages = {120--131}, year = {2011}, volume = {6671} } @Article{ ouzounis-soille2011ismm, author = {Ouzounis, G. and Soille, P.}, title = {Pattern spectra from partition pyramids and hierarchies}, doi = {10.1007/978-3-642-21569-8_10}, journal = {Lecture Notes in Computer Science}, pages = {108--119}, year = {2011}, volume = {6671} } @Article{ wilkinson-etal2011ismm, author = {Wilkinson, M. and Soille, P. and Pesaresi, M. and Ouzounis, G.}, title = {Concurrent computation of differential morphological profiles on giga-pixel images}, doi = {10.1007/978-3-642-21569-8_29}, journal = {Lecture Notes in Computer Science}, pages = {331-342}, year = {2011}, volume = {6671} } @InProceedings{ soille2011ismm_inproc, author = {Soille, P.}, title = {Preventing chaining through transitions while favouring it within homogeneous regions}, doi = {10.1007/978-3-642-21569-8_9}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {96--107}, year = {2011}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ ouzounis-soille2011ismm_inproc, author = {Ouzounis, G. and Soille, P.}, title = {Pattern spectra from partition pyramids and hierarchies}, doi = {10.1007/978-3-642-21569-8_10}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {108-119}, year = {2011}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ gueguen-soille2011ismm_inproc, author = {Gueguen, L. and Soille, P.}, title = {Frequent and dependent connectivities}, doi = {10.1007/978-3-642-21569-8_11}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {120-131}, year = {2011}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ wilkinson-etal2011ismm_inproc, author = {Wilkinson, M. and Soille, P. and Pesaresi, M. and Ouzounis, G.}, title = {Concurrent computation of differential morphological profiles on giga-pixel images}, doi = {10.1007/978-3-642-21569-8_29}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {331-342}, year = {2011}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ soille2011ismm_inproced, author = {Soille, P.}, title = {Preventing chaining through transitions while favouring it within homogeneous regions}, doi = {10.1007/978-3-642-21569-8_9}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {96--107}, year = {2011}, editor = {Soille, P. and Pesaresi, M. and Ouzounis, G.}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ ouzounis-soille2011ismm_inproced, author = {Ouzounis, G. and Soille, P.}, title = {Pattern spectra from partition pyramids and hierarchies}, doi = {10.1007/978-3-642-21569-8_10}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {108-119}, year = {2011}, editor = {Soille, P. and Pesaresi, M. and Ouzounis, G.}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @InProceedings{ gueguen-soille2011ismm_inproced, author = {Gueguen, L. and Soille, P.}, title = {Frequent and dependent connectivities}, doi = {10.1007/978-3-642-21569-8_11}, booktitle = {Proc. of 10th Int. Symp. on Mathematical Morphology}, pages = {120-131}, year = {2011}, editor = {Soille, P. and Pesaresi, M. and Ouzounis, G.}, volume = {6671}, series = {Lecture Notes in Computer Science}, publisher = {Springer-Verlag} } @Article{ poli-soille2011isprs, author = {Poli, D. and Soille, P.}, title = {Refinement of digital surface models through constrained connectivity partitioning of optical imagery}, doi = {10.5194/isprsarchives-XXXVIII-4-W19-245-2011}, journal = {Int. Arch. Photogramm. Remote Sens. Spatial Inf. Sci.}, year = {2011}, volume = {XXXVIII-4/W19}, pages = {245-250} } @InProceedings{ ouzounis-soille-pesaresi2011isrse, author = {G. Ouzounis and P. Soille and M. Pesaresi}, title = {Rubble detection from {VHR} aerial imagery data using differential morphological profiles}, url = {http://www.isprs.org/proceedings/2011/ISRSE-34/211104015Final00015.pdf}, booktitle = {Proc. of 34th Int. Symp. on Remote Sensing of the Environment}, year = {2011}, address = {Sydney}, month = apr, publisher = {Int. Center for Remote Sensing of Environment (ICRSE)} } @Article{ poggio-soille2011catena, author = {Poggio, L. and Soille, P.}, title = {A probabilistic approach to river network detection in digital elevation models}, journal = {CATENA}, year = {2011}, doi = {10.1016/j.catena.2011.07.001}, volume = {87}, number = {3}, pages = {341-350}, month = dec } @Article{ kemper-etal2011ijde, author = {Kemper, T. and Jenerowicz, M. and Pesaresi, M. and Soille, P.}, title = {Monitoring changes in the {M}enik farm {IDP} camps in {S}ri {L}anka using multi-temporal very high-resolution satellite data}, journal = {International Journal of Digital Earth}, year = {2011}, doi = {10.1080/17538947.2010.512430}, volume = {4}, number = {Supp.~1}, pages = {91-106} } @InProceedings{ wania-etal2011valgeo, author = {A. Wania and Kemper, T. and Ehrlich, D. and Soille, P. and Gallego ,J.}, title = {Definition of a reference dataset to assess the quality of building information extracted automatically from {VHR} satellite images}, doi = {10.2788/73045}, booktitle = {Proc. of 3rd Workshop on Validation of Geoinformation Products for Crisis Management (ValGeo)}, pages = {37-45}, year = {2011}, editor = {Corbane, C. and Carrion, D. and Broglia, M. and Pesaresi, M.}, number = {EUR~24948~EN} } @InProceedings{ gueguen-pesaresis-soille2011valgeo, author = {Gueguen, L. and Pesaresi, M. and Soille, P.}, title = {On the validation of an automatic roofless building counting process}, doi = {10.2788/73045}, booktitle = {Proc. of 3rd Workshop on Validation of Geoinformation Products for Crisis Management (ValGeo)}, pages = {47-53}, year = {2011}, editor = {Corbane, C. and Carrion, D. and Broglia, M. and Pesaresi, M.}, number = {EUR~24948~EN} } @InProceedings{ gueguen-pesaresi-soille2011igarss, author = {Gueguen, L. and Pesaresi, M. and Soille, P.}, title = {An interactive image mining tool handling gigapixel images}, doi = {10.1109/IGARSS.2011.6049373}, booktitle = {Proc. of IGARSS 2011}, pages = {1581-1584}, year = {2011}, month = jul, publisher = {IEEE Press} } @Article{ gueguen-soille-pesaresi2011, author = {Gueguen, L. and Soille, P. and Pesaresi, M. }, title = {Change detection based on information measure}, journal = {IEEE Transactions on Geoscience and Remote Sensing}, year = {2011}, doi = {10.1109/TGRS.2011.2141999}, volume = {49}, number = {11}, pages = {4503-4515}, month = nov } @InProceedings{ jenerowicz-kemper-soille2011spie, author = {Jenerowicz, M. and Kemper, T. and Soille, P.}, title = {An automated procedure for the detection of {IDP}'s dwellings using {VHR} satellite imagery}, doi = {10.1117/12.898187}, booktitle = {Proc. SPIE 8180}, year = {2011} } @Misc{ ouzounis-etal2011un-nairobi, author = {Ouzounis, G. and Gueguen, L. and Soille, P. and Pesaresi, M.}, title = {Engines and Algorithms}, howpublished = {Slides of oral presentation at the 1st International Workshop Remote Sensing for the Environment for the Sub Saharian Regions}, year = {2011} } @Article{ gueguen-etal2012grsl, author = {Gueguen, L. and Pesaresi, M. and Gerhardinger, A. and Soille, P.}, title = {Characterising and counting roofless buildings in very high resolution images}, journal = {Geoscience and Remote Sensing Letters}, year = {2012}, doi = {10.1109/LGRS.2011.21611750}, volume = {9}, number = {1}, pages = {114-118}, month = jan } @Article{ poggio-soille2012hyp, author = {Poggio, L. and Soille, P.}, title = {Influence of pit removal methods on river network position}, journal = {Hydrological Processes}, year = {2012}, doi = {10.1002/hyp.8290}, volume = {26}, pages = {1984-1990} } @Article{ soille-najman2012lncs, author = {Soille, P. and Najman, L.}, title = {On morphological hierarchical representations for image processing and spatial data clustering}, journal = {Lecture Notes in Computer Science}, year = {2012}, doi = {10.1007/978-3-642-32313-3_4}, volume = {7346}, pages = {43-67} } @InCollection{ soille-najman2012lncs_incolled, author = {Soille, P. and Najman, L.}, title = {On morphological hierarchical representations for image processing and spatial data clustering}, booktitle = {Applications of Discrete Geometry and Mathematical Morphology}, doi = {10.1007/978-3-642-32313-3_4}, pages = {43-67}, publisher = {Springer}, year = {2012}, editor = {K\"othe, U. and Montanvert, A. and Soille, P.}, volume = {7346}, series = {Lecture Notes in Computer Science} } @InCollection{ soille-najman2012lncs_incoll, author = {Soille, P. and Najman, L.}, title = {On morphological hierarchical representations for image processing and spatial data clustering}, booktitle = {Applications of Discrete Geometry and Mathematical Morphology}, doi = {10.1007/978-3-642-32313-3_4}, pages = {43-67}, publisher = {Springer}, year = {2012}, volume = {7346}, series = {Lecture Notes in Computer Science} } @Book{ koethe-montanvert-soille2012, editor = {K\"othe, U. and Montanvert, A. and Soille, P.}, title = {Applications of Discrete Geometry and Mathematical Morphology}, publisher = {Springer}, year = {2012}, doi = {10.1007/978-3-642-32313-3}, volume = {7346}, series = {Lecture Notes in Computer Science}, address = {Berlin} } @Article{ ouzounis-pesaresi-soille2012, author = {Ouzounis, G. and Pesaresi, M. and Soille, P.}, title = {Differential area profiles: decomposition properties and efficient computation}, journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence}, year = {2012}, doi = {10.1109/TPAMI.2011.245}, volume = {34}, number = {8}, pages = {1533-1548}, month = aug } @Article{ poli-soille2012, author = {Poli, D. and Soille, P.}, title = {Digital surface models extraction from {ISPRS} benchmark stereo data and refinement through constrained connectivity partitioning}, journal = {Pho\-to\-gram\-me\-trie-Fern\-er\-kun\-dung-Geo\-in\-for\-ma\-tion}, year = {2012}, doi = {10.1127/1432-8364/2012/0120}, volume = {2012}, number = {4}, pages = {317-329}, month = aug } @TechReport{ ouzounis-soille2012tr, author = {Ouzounis, G. and Soille, P.}, title = {The Alpha-Tree Algorithm: Theory, Algorithm, and Applications}, institution = {Joint Research Centre, European Commission}, year = {2012}, doi = {10.2788/48773}, number = {25500~EN}, month = sep } @Proceedings{ soille-etal2012iimproc, title = {Proc. of 8th Image Information Mining: Knowledge Discovery from Earth Observation Data}, year = {2012}, doi = {10.2788/49465}, editor = {Soille, P. and Iapaolo, M. and Marchetti, P.G. and Datcu, M.}, address = {German Aerospace Centre (DLR), Oberpfaffenhofen, Germany}, month = oct, organization = {ESA-EUSC-JRC}, publisher = {Joint Research Centre of the European Commission} } @InProceedings{ gueguen-etal2012iim, author = {Gueguen, L. and Ouzounis, G. and Pesaresi, M. and Soille, P.}, title = {Tree based representations for fast information mining from {VHR} images}, doi = {10.2788/49465}, booktitle = {Proc. of 8th Conference on Image Information Mining}, pages = {15-20}, month = oct, year = {2012}, editor = {Soille, P. and Iapaolo, M. and Marchetti, P.G. and Datcu, M.}, organization = {ESA-EUSC-JRC}, publisher = {Joint Research Centre of the European Commission} } @InProceedings{ ouzounis-etal2012iim, author = {Ouzounis, G. and Syrris, V. and Gueguen, L. and Soille, P.}, title = {The switchboard platform for interactive image information mining}, doi = {10.2788/49465}, booktitle = {Proc. of 8th Conference on Image Information Mining}, pages = {26-30}, month = oct, year = {2012}, editor = {Soille, P. and Iapaolo, M. and Marchetti, P.G. and Datcu, M.}, organization = {ESA-EUSC-JRC}, publisher = {Joint Research Centre of the European Commission} } @InProceedings{ kemper-gueguen-soille2012spie, author = {Kemper, T. and Gueguen, L. and Soille, P.}, title = {Improving the automated detection of refugee/{IDP} dwellings using the multispectral bands of {W}orld{V}iew-2 satellite}, doi = {10.1117/12.919841}, booktitle = {Proc. of Algorithms and Technologies for Multispectral, Hyperspectral, and Ultraspectral Imagery XVIII}, year = {2012}, editor = {Shen, S. and Lewis, P.}, volume = {8390}, publisher = {SPIE} } @InProceedings{ gueguen-velasco-soille2012igarss, author = {Gueguen, L. and Velasco-Forero, S. and Soille, P.}, title = {Edge extraction by statistical dependence analysis: application to a multi-angular {Wo}rld{V}iew-2 series}, doi = {10.1109/IGARSS.2012.6350679}, booktitle = {Proc. Int. Symp. on Geoscience and Remote Sensing (IGARSS)}, pages = {3447-3450}, year = {2012}, address = {Munich}, month = jul, organization = {IEEE} } @InProceedings{ gueguen-soille-pesaresi2012igarss, author = {Gueguen, L. and Soille, P. and Pesaresi, M.}, title = {A new built-up presence index based on density of corners}, doi = {10.1109/IGARSS.2012.6352386}, booktitle = {Proc. Int. Symp. on Geoscience and Remote Sensing (IGARSS)}, pages = {5398-5401}, year = {2012}, address = {Munich}, month = jul, publisher = {IEEE} } @Book{ pesaresi-etal2012ghsltr, author = {Pesaresi, M. and Blaes, X. and Ehrlich D. and Ferri, S. and Gueguen, L. and Haag, F. and Halkia, S. and Heinzel, J. and Kauffmann, M. and Kemper, T. and Ouzounis, G. and Scavazzon, M. and Soille, P. and Syrris, V. and Zanchetta L.}, title = {A Global Human Settlement Layer from optical high resolution imagery: Concept and first results}, publisher = {Joint Research Centre of the European Commission}, year = {2012}, doi = {10.2788/73897} } @Article{ ehrlich-etal2013nh, author = {Ehrlich, D. and Kemper, T. and Blaes, X. and Soille, P.}, title = {Extracting building stock information from optical satellite imagery for mapping earthquake exposure and its vulnerability}, journal = {Natural Hazards}, year = {2013}, doi = {10.1007/s11069-012-0482-0}, volume = {68}, number = {1}, pages = {79-95}, month = {Aug} } @Article{ pesaresi-etal2013jstars, author = {Pesaresi, M. and Huadong, G. and Blaes, X. and Ehrlich, D. and Ferri, S. and Gueguen, L. and Halkia, M. and Kauffmann, M. and Kemper, T. and Lu, L. and Marin-Herrera, M. and Ouzounis, G. and Scavazzon, M. and Soille, P. and Syrris, V. and Zanchetta, L.}, title = {A global human settlement layer form optical {HR/VHR} {RS} data: concepts and first results}, journal = {Journal of Earth Observation Applications}, year = {2013}, doi = {10.1109/JSTARS.2013.2271445}, volume = {6}, number = {5}, pages = {2102-2131} } @Article{ pesaresi-etal2013jstars_etal, author = {Pesaresi, M. and et al.}, title = {A global human settlement layer form optical {HR/VHR} {RS} data: concepts and first results}, journal = {Journal of Earth Observation Applications}, year = {2013}, doi = {10.1109/JSTARS.2013.2271445}, volume = {6}, number = {5}, pages = {2102-2131} } @Article{ pesaresi-etal2013jstars_with-note, author = {Pesaresi, M. and Huadong, G. and Blaes, X. and Ehrlich, D. and Ferri, S. and Gueguen, L. and Halkia, M. and Kauffmann, M. and Kemper, T. and Lu, L. and Marin-Herrera, M. and Ouzounis, G. and Scavazzon, M. and Soille, P. and Syrris, V. and Zanchetta, L.}, title = {A global human settlement layer form optical {HR/VHR} {RS} data: concepts and first results}, journal = {Journal of Earth Observation Applications}, year = {2013}, doi = {10.1109/JSTARS.2013.2271445}, volume = {6}, number = {5}, pages = {2102-2131} } @InProceedings{ lu-etal2013jurse, author = {Lu, L. and Guo, H. and Pesaresi, M. and Soille, P. and Ferri, S.}, title = {Automatic Recognition of Built-up Areas in {C}hina Using {CBERS-2B} {HR} Data}, doi = {10.1109/JURSE.2013.6550667}, booktitle = {Proc. of Urban Remote Sensing Event (JURSE) 2013}, pages = {65-68}, year = {2013}, publisher = {IEEE} } @TechReport{ soille2013tr, author = {Soille, P.}, title = {2.5m pan-{E}uropean natural colour mosaic with adaptive seamlines and cloud minimisation}, institution = {Joint Research Centre of the European Commission}, year = {2013} } @Article{ velasco-angulo-soille2014jmiv, author = {Velasco-Forero, S. and Angulo, J. and Soille, P.}, title = {Conditional toggle mappings: principles and applications}, journal = {Journal of Mathematical Imaging and Vision}, year = {2014}, doi = {10.1007/s10851-013-0429-4}, volume = {48}, number = {3}, pages = {544-565}, month = mar } @Article{ gueguen-velasco-soille2014jmiv, author = {Gueguen, L. and Velasco-Forero, S. and Soille, P.}, title = {Local mutual information for dissimilarity-based image segmentation}, journal = {Journal of Mathematical Imaging and Vision}, year = {2014}, doi = {10.1007/s10851-013-0432-9}, volume = {48}, number = {3}, pages = {625-644}, month = mar } @Proceedings{ soille-etal2014iimproc, title = {Proc. of ESA-EUSC-JRC 9th conference on Image Information Mining}, subtitle = {The {S}entinels Era}, year = {2014}, doi = {10.2788/25852}, editor = {Soille, P. and Marchetti, P.G. and Iapaolo, M. and Colaiacomo, L. and Datcu, M.}, address = {University Politehnica of Bucharest (Romania)}, month = mar, organization = {ESA-EUSC-JRC}, publisher = {Joint Research Centre of the European Commission}, url = {http://rssportal.esa.int/tiki-index.php?page=ESA-EUSC-JRC-2014} } @Misc{ soille2014core3viewer, author = {Soille, P.}, title = {Copernicus {CORE3} {SPOT} 2.5 Pan-sharpened Pan-{E}uropean Mosaic: Core\_003 Mosaic (Seamlines)}, url = {http://cidportal.jrc.ec.europa.eu/copernicus/services/webviewer/core003/}, year = {2014}, institution = {Joint Research Centre of the European Commission} } @TechReport{ soille2014core3mosaic, author = {Soille, P.}, title = {Morphological mosaicing of Copernicus {CORE3} {SPOT} 2.5 pan-sharpened pan-{E}uropean imagery with automatic seamline generation}, institution = {Joint Research Centre of the European Commission}, year = {2014}, optkey = {}, opttype = {}, optnumber = {}, optaddress = {}, optmonth = {}, optannote = {} } @InProceedings{ soille2014s24s, author = {Soille, P.}, title = {Towards the Compositing and Mosaicing of {S}entinel-2 Images Using Quality and Spatial Coherence Constraints}, optcrossref = {}, url = {http://seom.esa.int/S2forScience2014/index.php}, booktitle = {Proc. of Sentinel-2 for Science Workshop}, optpages = {}, year = {2014}, opteditor = {}, optvolume = {}, optnumber = {}, optseries = {}, optaddress = {}, month = may, organization = {ESA}, optpublisher = {}, optnote = {}, optannote = {} } @Proceedings{ soille-marchetti2014bids, title = {Proc. of the 2014 Conference on Big Data from Space (BiDS'14)}, year = {2014}, doi = {10.2788/1823}, editor = {Soille, P. and Marchetti, P.G.}, address = {Frascati, Italy}, month = nov, organization = {ESA-JRC-SatCen}, publisher = {Publications Office of the European Union} } @InProceedings{ soille2014bids, author = {Soille, P.}, title = {Seamless Mosaicing of Very High Resolution Satellite Data at Continental Scale}, booktitle = {Proc. of the 2014 Conference on Big Data from Space (BiDS'14)}, pages = {222-223}, year = {2014}, editor = {Soille, P. and Marchetti, P.G.}, doi = {10.5281/zenodo.3248602}, url = {https://cidportal.jrc.ec.europa.eu/services/webview/jeodpp/databrowser/?default=core003Seamline}, month = nov, publisher = {Publications Office of the European Union} } @Book{ syrris-etal2015tr, author = {Syrris, V. and Grazzini, J. and De Marchi, D. and Soille, P. and Burger, A.}, title = {Survey on the current and future user requirements in the framework of the JRC {E}arth Oservation {\&} Social Sensing Big Data pilot project}, publisher = {Joint Research Centre of the European Commission}, year = {2015}, series = {JRC Technical Report} } @InProceedings{ pesaresi-etal2015muas, author = {Pesaresi, M. and Ehrlich, D. and Ferri, S. and Florczyk, A. and Freire, S. and Halkia, M. and Julea, A. and Kemper, T. and Soille, P. and Syrris, V.}, title = {The Global Human Settlement Layer}, url = {http://due.esrin.esa.int/muas2015/files/Abstract_Book_MUAS.pdf}, booktitle = {Mapping Urban Areas from Space (MUAS) conference (abstract book)}, year = {2015}, page = {2-3}, address = {Frascati, Italy}, publisher = {European Space Agency} } @Article{ pesaresi-etal2015isprs, author = {M. Pesaresi and D. Ehrlich and S. Ferri and A. Florczyk and S. Freire and F. Haag and M. Halkia and A. M. Julea and T. Kemper and P. Soille}, title = {Global Human Settlement Analysis for Disaster Risk Reduction}, journal = {Int. Arch. Photogramm. Remote Sens. Spatial Inf. Sci.}, year = {2015}, doi = {10.5194/isprsarchives-XL-7-W3-837-2015}, volume = {XL-7/W3}, pages = {837-843} } @Misc{ soille2015cern, author = {Soille, P.}, title = {JRC Big Data Needs and Directions}, howpublished = {Oral presentation at CERN}, year = {2015}, url = {https://cds.cern.ch/record/2030180} } @Article{ florczyk-etal2016jstars, author = {Florczyk, A. J. and Ferri, S. and Syrris, V. and Kemper, T. and Halkia, M. and Soille, P. and Pesaresi, M. }, title = {A New European Settlement Map From Optical Remotely Sensed Data}, journal = {IEEE Journal of Selected Topics in Applied Earth Observations and Remote Sensing}, year = {2016}, doi = {10.1109/JSTARS.2015.2485662}, volume = {9}, number = {5}, pages = {1978-1992}, month = may } @InProceedings{ burger-soille2016cs3, author = {Burger, A. and Soille, P.}, title = {Towards an infrastucture for interactive {E}arth {O}bservation data analysis and processing}, doi = {10.5281/zenodo.44783}, booktitle = {Book of Abstacts of Cloud Services for Synchronisation and Sharing}, year = {2016}, editor = {Chan, B.}, pages = {27}, publisher = {CERN}, organization = {ETH Z{\"u}rich} } @TechReport{ pesaresi-etal2016trghsl, title = {Operating procedure for the production of the Global Human Settlement Layer from {L}andsat data of the epochs 1975, 1990, 2000, and 2014}, author = {Pesaresi, M. and Ehrlich, D. and Ferri, S. and Florczyk, A. J. and Freire, S. and Halkia, M. and Julea, A. and Kemper, T. and Soille, P. and Syrris, V.}, publisher = {Publications Office of the European Union}, institution = {Joint Research Centre of the European Commission}, year = {2016}, number = {EUR 27741 EN}, opttype = {JRC Technical Report}, doi = {10.2788/253582} } @Proceedings{ soille-marchetti2016bids, title = {Proc. of the 2016 Conference on Big Data from Space (BiDS'16)}, year = {2016}, doi = {10.2788/854791}, editor = {Soille, P. and Marchetti, P.G.}, address = {Tenerife, Spain}, month = mar, organization = {ESA-JRC-SatCen}, publisher = {Publications Office of the European Union} } @InProceedings{ soille-etal2016bids, author = {P. Soille and A. Burger and D. Rodriguez and V. Syrris and V. Vasilev}, title = {Towards a {JRC} {E}arth Observation Data and Processing Platform}, pages = {65-68}, doi = {10.5281/zenodo.3248713}, booktitle = {Proc. of the 2016 Conference on Big Data from Space (BiDS'16)}, year = {2016}, editor = {Soille, P. and Marchetti, P.G.}, publisher = {Publications Office of the European Union} } @InProceedings{ soille-etal2016bids_short, author = {P. Soille and A. Burger and D. Rodriguez and V. Syrris and V. Vasilev}, title = {Towards a {JRC} {E}arth Observation Data and Processing Platform}, pages = {65-68}, doi = {10.5281/zenodo.3248713}, booktitle = {Proc. of BiDS'16}, year = {2016} } @InProceedings{ syrris-rodriguez-soille2016bids, author = {V. Syrris and D. Rodriguez and P. Soille}, title = {Task allocation in high performance processing of geospatial data}, pages = {111-114}, url = {http://publications.jrc.ec.europa.eu/repository/bitstream/JRC98347/syrris-etal2016bids.pdf}, doi = {10.2788/854791}, booktitle = {Proc. of the 2016 Conference on Big Data from Space (BiDS'16)}, year = {2016}, editor = {Soille, P. and Marchetti, P.G.}, publisher = {Publications Office of the European Union} } @Article{ marchetti-soille-bruzzone2016grsm, author = {Marchetti, P.G. and Soille, P. and Bruzzone, L.}, title = {A Special Issue on Big Data from Space for Geoscience and Remote Sensing}, journal = {IEEE Geoscience and Remote Sensing Magazine}, year = {2016}, doi = {10.1109/MGRS.2016.2586852}, pages = {7-9}, volume = {4}, number = {3}, month = sep } @Article{ pesaresi-etal2016rs, author = {Pesaresi, M. and Corbane, C. and Julea, A. and Florczyk, A. and Syrris, V. and Soille, P.}, title = {Assessment of the Added-Value of {S}entinel-2 for Detecting Built-up Areas}, journal = {Remote Sensing}, year = {2016}, doi = {10.3390/rs8040299}, volume = {8}, number = {4}, pages = {299} } @TechReport{ syrris-etal2016tr-sandbox-use-cases, author = {Syrris, V. and Kempeneers, P. and Rodriguez, D. and Soille, P.}, title = {Sandbox Computing Environment of the {JRC} Earth Observation Data and Processing Platform: 2016 Use-Case Report}, institution = {Joint Research Centre of the European Commission}, year = {2016}, url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC105159}, number = {JRC105159} } @TechReport{ burger-etal2016tr-idps, author = {Burger, A. and De Marchi, D. and Eyraud, F. and Gregory, I. and Kempeneers, P. and Rodriguez, D. and Soille, P. and Vasilev, V.}, title = {{JRC} Earth Observation Data and Processing Platform: Integrated Data and Processing System}, institution = {Joint Research Centre of the European Commission}, year = {2016}, url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC104507}, number = {JRC104507} } @Misc{ soille2016eodcforum, author = {Soille, P.}, title = {Big Data Solutions for {EO} pursued at {JRC}}, howpublished = {Slides of presentation at 2016 EODC FORUM, 31st May--1st June, Vienna, Austria}, year = {2016} } @InProceedings{ burger-soille2017cs3, author = {Burger, A. and Soille, P.}, title = {Web-based interactive analysis and visualisation of {E}arth {O}bservation data at petabyte scale}, url = {https://indico.cern.ch/event/565381/contributions/2402650/contribution.pdf}, booktitle = {Book of Abstacts of Cloud Services for Synchronisation and Sharing}, year = {2017} } @InProceedings{ burger-etal2017eosworkshop, author = {Burger, A. and Vasilev, V. and Soille, P. and Iztok, G. and Rodriguez, D.}, title = {{EOS} as storage back-end for {E}arth {O}bservation data processing at the {EC} {J}oint {R}esearch {C}entre}, url = {https://indico.cern.ch/event/591485/contributions/2450251/}, booktitle = {EOS Workshop}, year = {2017}, month = feb, address = {Ginevra, Switzerland}, organization = {CERN}, publisher = {CERN} } @Article{ soille-etal2017fgcs, author = {Soille, P. and Burger, A. and De Marchi, D. and Kempeneers, P. and Rodriguez, D. and Syrris, V. and Vasilev, V.}, title = {A Versatile Data-Intensive Computing Platform for Information Retrieval from Big Geospatial Data}, journal = {Future Generation Computer Systems}, year = {2018}, doi = {10.1016/j.future.2017.11.007}, volume = {81}, number = {4}, pages = {30-40}, month = apr } @Book{ simonetti-etal2017tr, author = {Simonetti, D. and Marelli, A. and Rodriguez, D. and Veselin, V. and Strobl, P. and Burger, A. and Soille, P. and Achard, F. and Eva, H. and Stibig, H.-J. and Beuchle, R.}, title = {Sentinel-2 {W}eb platform for {REDD$+$} monitoring}, subtitle = {Online web platform for browsing and processing {S}entinel-2 data for forest cover monitoring over the {T}ropics}, publisher = {Joint Research Centre of the European Commission}, year = {2017}, doi = {10.2760/790249}, series = {JRC Technical Report} } @Article{ santamaria-etal2017rs, author = {Santamaria, C. and Alvarez, M. and Greidanus, H. and Syrris, V. and Soille, P. and Argentieri, P.}, title = {Mass processing of {S}entinel-1 images for maritime surveillance}, journal = {Remote Sensing}, year = {2017}, doi = {10.3390/rs9070678}, volume = {9}, number = {7}, pages = {678/1-678/20} } @Misc{ corbane-etal2017worldcover, author = {Corbane, C. and Pesaresi, M. and Syrris, V. and Kemper, T. and Politis, P. and Soille, P. and Florczyk, A. and Sabo, F. and Rodriguez, D. and Maffenini, L. and Ferri, S.}, title = {Global Mapping of Human settlements with {S}entinel-1 and {S}entinel-2 data: Recent developments in the {G}lobal {H}uman {S}ettlement {L}ayer}, howpublished = {Slides of presentation at WorldCover'2017, ESA, Frascati, Italy}, month = mar, year = {2017}, url = {http://worldcover2017.esa.int/files/2.2-p1.pdf} } @Article{ corbane-etal2017bed, title = {Big earth data analytics on {S}entinel-1 and {L}andsat imagery in support to global human settlements mapping}, author = {Christina Corbane and Martino Pesaresi and Panagiotis Politis and Vasileios Syrris and Florczyk, Aneta J. and Pierre Soille and Luca Maffenini and Armin Burger and Veselin Vasilev and Dario Rodriguez and Filip Sabo and Lewis Dijkstra and Thomas Kemper}, journal = {Big Earth Data}, year = {2017}, number = {1--2}, pages = {118-144}, volume = {1}, doi = {10.1080/20964471.2017.1397899} } @Misc{ soille2017eodcforum, author = {Soille, P.}, title = {Big EO data at JRC: activities, ideas, and vision}, howpublished = {Slides of presentation at 2017 EODC FORUM, 9--10 May, Vienna, Austria}, year = {2017} } @InProceedings{ vasilev-etal2017htcondor, author = {Vasilev, V. and Rodriguez, D. and Soille, P. and Burger, A. }, title = {Flexible and Cost-effective Petabyte-Scale Architecture with {HTCondor} Processing and {EOS} Storage Backend for {E}arth {O}bservation Applications}, url = {https://indico.cern.ch/event/611296/contributions/2604353/}, booktitle = {Book of abstracts of HTCondor European Conference 2017}, year = {2017}, address = {Hamburg, Germany}, organization = {DESY}, publisher = {CERN} } @InProceedings{ rodriguez-etal2017htcondor, author = {Rodriguez, D. and Vasilev, V. and Soille, P.}, title = {Experiences with {HTCondor} Universes on a Petabyte Scale Platform for {E}arth {O}bservation Data Processing}, url = {https://indico.cern.ch/event/611296/contributions/2604355/}, booktitle = {Book of abstracts of HTCondor European Conference 2017}, year = {2017}, address = {Hamburg, Germany}, organization = {DESY}, publisher = {CERN} } @Misc{ santamaria-etal2017malta, author = {Santamaria, C. and Alvarez, M. and Greidanus, H. and Syrris, V. and Soille, P. and Argentieri, P.}, title = {Ship traffic in the {M}ed {S}ea}, howpublished = {Poster presented at Space Solutions for Resilience in the Mediterranean, Malta, 26--27/6}, year = {2017} } @Misc{ soille2017msparsajeodpp, author = {Soille, P.}, title = {Petabyte Scale Processing and Analysis for Remote Sensing Applications}, howpublished = {Slides presented at the multivariate Signal Processing and Analysis for Remote Sensing Applications ---multivariate Signal Processing and Analysis for Remote Sensing Applications--- mSPARSA 2017, Bra\,sov, Romania}, month = jul, year = {2017} } @Misc{ soille2017msparsaconnectivity, author = {Soille, P.}, title = {Alpha-Connectivity: Principles and Applications}, howpublished = {Slides presented at the multivariate Signal Processing and Analysis for Remote Sensing Applications ---multivariate Signal Processing and Analysis for Remote Sensing Applications--- mSPARSA 2017, Bra\,sov, Romania}, month = jul, year = {2017} } @Proceedings{ soille-marchetti2017bids, title = {Proc. of the 2017 Conference on Big Data from Space (BiDS'17)}, year = {2017}, doi = {10.2760/383579}, editor = {Soille, P. and Marchetti, P.G.}, address = {Toulouse, France}, month = nov, organization = {ESA-JRC-SatCen}, publisher = {Publications Office of the European Union} } @InProceedings{ corbane-etal2017bids_short, author = {C. Corbane and M. Pesaresi and P. Politis and V. Syrris and Florczyk, A.J. and P. Soille and L. Maffenini and A. Burger and V. Vasilev and D. Rodriguez Aseretto and F. Sabo and L. Dijkstra and T. Kemper}, title = {Mass processing of {S}entinel-1 and {L}andsat data for mapping human settlements at global level}, pages = {52-55}, doi = {10.2760/383579}, booktitle = {Proc. of BiDS'17}, year = {2017} } @InProceedings{ demarchi-etal2017bids_short, author = {De Marchi, D. and Burger, A. and Kempeneers, P. and Soille, P.}, title = {Interactive visualisation and analysis of geospatial data with {J}upyter}, pages = {71-74}, doi = {10.5281/zenodo.3248741}, booktitle = {Proc. of BiDS'17}, year = {2017} } @InProceedings{ soille-etal2017bids_short, author = {Soille, P. and Burger, A. and De Marchi, D. and Hasenohr, P. and Kempeneers, P. and Rodriguez, D. and Syrris, V. and Vasilev, V.}, title = {The {JRC} {E}arth {O}bservation {D}ata and {P}rocessing {P}latform}, pages = {271-274}, doi = {10.5281/zenodo.3239211}, booktitle = {Proc. of BiDS'17}, year = {2017} } @InProceedings{ kempeneers-soille2017bids_short, author = {Kempeneers, P. and Soille, P.}, title = {Optimising {S}entinel-2 image selection in a big data context}, pages = {177-180}, doi = {10.2760/383579}, booktitle = {Proc. of BiDS'17}, year = {2017} } @InProceedings{ syrris-corbane-soille2017bids_short, author = {Syrris, V. and Corbane, C. and Soille, P.}, title = {A global mosaic from {C}opernicus {S}entinel-1 data}, pages = {267-270}, doi = {10.5281/zenodo.3371079}, booktitle = {Proc. of BiDS'17}, year = {2017} } @InProceedings{ martinez-etal2017, author = {Martinez, L. and Di Leo, M. and Chemin, Y. and Zarco-Tejada, P.J. and de La Fuente Martin, B. and Rodriguez-Aseretto, R. and Kempeneers, P. and Soille, P. and Beck, P.}, title = {Detecting stressed and pest-affected trees in aerial photos through machine learning: a proof of concept}, url = {https://git.osgeo.org/gogs/foss4g-europe/foss4g-europe-2017-paris/src/master/presentations/2017-07-21/academic_track/foss4g-europe-2017-Detecting_stressed_and_pest-affected_trees_in_aerial_photos_through_machine_learning_a_proof_of_concept-MDiLeo-LMartinez-YChemin-P-JZarco-Tejada-BdeLaFutente-Martin-BPieterSA.pdf}, booktitle = {Conference on Free and Open Source Software for Geospatial (FOSS4G)-Europe}, year = {2017}, month = jul, address = {Paris} } @Book{ pebesma-etal2017openeo, author = {Pebesma, Edzer and Wagner, Wolfgang and Schramm, Matthias and Von Beringe, Alexandra and Paulik, Christoph and Neteler, Markus and Reiche, Johannes and Verbesselt, Jan and Dries, Jeroen and Goor, Erwin and Mistelbauer, Thomas and Briese, Christian and Notarnicola, Claudia and Monsorno, Roberto and Marin, Carlo and Jacob, Alexander and Kempeneers, Pieter and Soille, Pierre}, title = {{OpenEO}: a Common, Open Source Interface Between Earth Observation Data Infrastructures and Front-End Applications}, month = nov, year = {2017}, doi = {10.5281/zenodo.1065474}, publisher = {Zenodo} } @TechReport{ kemper-etal2017ghslv1, author = {T. Kemper and C. Corbane and D. Ehrlich and Florczyk, A.J. and S. Freire and L. Maffenini and M. Melchiorr and M. Pesaresi and P. Politis and M. Schiavina and P. Soille and V. Syrris}, title = {{GHS} built-up grid, derived from {L}andsat, multitemporal (1975, 1990, 2000, 2014) {IR} 2017 Version 1.0}, institution = {Joint Research Centre of the European Commission}, year = {2017}, url = {http://cidportal.jrc.ec.europa.eu/ftp/jrc-opendata/GHSL/GHS_BUILT_LDSMT_GLOBE_R2015B/}, ps-url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC109041} } @TechReport{ kempeneers-etal2017tr-sandbox-use-cases, author = {Kempeneers, P. and Syrris, V. and Rodriguez, D. and Marletta, L. and De Marchi, D. and Burger, A. and Soille, P.}, title = {Sandbox Computing Environment of the {JRC} Earth Observation Data and Processing Platform: 2017 Use-Case Report}, institution = {Joint Research Centre of the European Commission}, year = {2017}, number = {JRC110242}, url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC110242} } @TechReport{ demarchi-kempeneers-soille2017tr-user-manual, author = {De Marchi, D. Kempeneers, P. and Soille, P.}, title = {JEODPP Interactive Library: User Guide. Release 1.0}, url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC110356}, institution = {Joint Research Centre of the European Commission}, year = {2017}, number = {JRC110356} } @Article{ kempeneers-soille2017bed, title = {Optimizing {S}entinel-2 image selection in a Big Data context}, author = {Kempeneers, P. and Soille, P.}, journal = {Big Earth Data}, year = {2017}, number = {1--2}, pages = {145--158}, volume = {1}, doi = {10.1080/20964471.2017.1407489} } @Misc{ demarchi-kempeneers-soille2017geo, author = {Kempeneers, P. and De Marchi, D. and Soille, P.}, title = {Big Geospatial Data for Policy}, howpublished = {Poster presented at the GEO-WEEK, Washington D.C.}, year = {2017} } @TechReport{ burger-kliment-tognoli2017tr-internal, author = {Burger, A. and Kliment, Tomas and Tognoli, Pier Valerio}, title = {JEODPP Data Ingestion and Management}, institution = {Joint Research Centre of the European Commission}, year = {2017}, url = {http://skp.jrc.cec.eu.int/skp/showPub?id=JRC110143}, number = {JRC110143} } @Book{ castello-etal2017km4p, author = {P. Castello and A. Belward and Goenaga Beldarrain, X. and La Placa, G. and Lavalle, C. and Loekkemyhr, P. and Mair, D. and Marcaletti, L. and Marin Ferrer, M. and Paruolo, P. and Raykovska, M. and Saisana, M. and S. Schade and P. Soille and D. Tarchi and V. Tarditi and X. Troussard and E. Tzimas and F. Wastin and M. Wilikens and C. Wittwehr}, ps-editor = {P. Castello}, title = {Knowledge Management for Policy: Stocktaking of one year of {JRC} activities}, publisher = {Joint Research Centre of the European Commission}, year = {2017}, doi = {10.2760/105829}, number = {JRC107777} } @InProceedings{ edzer-etal2018egu, author = {Pebesma, Edzer and Wagner, Wolfgang and Soille, Pierre and Kadunc, Miha and Gorelick, Noel and Schramm, Matthias and Verbesselt, Jan and Reiche, Johannes and Appel, Marius and Dries, Jeroen and Jacob, Alexander and Neteler, Markus and Gebbert, Soeren and Briese, Christian and Kempeneers, Pieter}, title = {{openEO:} an open {API} for cloud-based big {E}arth {O}bservation processing platforms}, url = {https://meetingorganizer.copernicus.org/EGU2018/EGU2018-4957-1.pdf}, booktitle = {Geophysical Research Abstracts}, year = {2018}, volume = {20}, number = {EGU2018-4957-1} } @InProceedings{ burger-etal2018cs3, author = {Burger, Armin amd Hasenohr, Paul and De Marchi, Davide and Soille, Pierre}, title = {Integrated processing and sharing services for geospatial data}, doi = {10.5281/zenodo.1157141}, booktitle = {Book of abstracts of CS3 2018 - Workshop on Cloud Storage Synchronization and Sharing Services}, year = {2018}, editor = {Chan, Belinda}, pages = {9}, publisher = {CERN} } @InProceedings{ burger-vasilev-soille2018eos, author = {Burger, Armin and Veselin, Vasilev and Soille, Pierre}, title = {{EOS} as storage back-end for geospatial data analysis}, url = {https://indico.cern.ch/event/656157/contributions/2866322/attachments/1594530/2524833/CERN_EOS-WS_Burger_Vasilev_20180205.pdf}, booktitle = {CERN EOS Workshop}, year = {2018} } @Misc{ schramm-etal2018phiweek, url = {http://phiweek.esa.int/}, author = {Schramm, Matthias and Pebesma, Edzer and Wagner, Wolfgang and Soille, Pierre and Kadunc, Miha and Gorelick, Noel and Verbesselt, Jan and Reiche, Johannes and Appel, Marius and Dries, Jeroen and Jacob, Alexander and Goesswein, Bernhard and Neteler, Markus and Gebbert, Soeren and Briese, Christian and Kempeneers, Pieter}, title = {{openEO} --- {C}ommon open source interface between {E}arth {O}bservation data infrastructures {\&} front-end applications}, howpublished = {Presentation at ESA Earth Observation {$\mathbf{\phi}$}-week - EO Open Science and Future EO}, month = oct, year = {2018} } @Article{ syrris-etal2018tbd, author = {Syrris, V. and Corbane, C. and Pesaresi, M. and Soille, P.}, title = {Mosaicking {C}opernicus {S}entinel-1 data at global scale}, journal = {IEEE Transactions on Big Data}, year = {2018}, doi = {10.1109/TBDATA.2018.2846265}, optvolume = {}, optnumber = {}, optpages = {}, optmonth = {} } @TechReport{ syrris-etal2018s1mosaic, author = {Syrris, V. and Corbane, C. and Pesaresi, M. and Soille, P.}, title = {Mosaic of Copernicus {S}entinel-1 Data at Global Scale}, institution = {Joint Research Centre of the European Commission}, year = {2018}, doi = {10.2905/jrc-bigdataeoss-s1-mosaic}, url = {https://cidportal.jrc.ec.europa.eu/services/webview/jeodpp/databrowser/?default=jeodppS1Mosaic2016} } @Misc{ demarchi-soille2018euroscipy, author = {De Marchi, D. and Soille, P.}, title = {Big geospatial data visualization and analysis in {J}upyter}, howpublished = {Presentation at the EuroSciPy 2018 conference, Trento, Italy}, month = sep, year = {2018} } @InProceedings{ rodriguez-soille2018htcondor, author = {Rodriguez, D. and Soille, P.}, title = {A versatile environment for large-scale geospatial data processing with {HTCondor}}, url = {https://indico.cern.ch/event/611296/contributions/2604355/}, booktitle = {Book of abstracts of HTCondor European Conference 2018}, year = {2018}, address = {Oxford, UK}, organization = {RAL}, publisher = {CERN} } @Misc{ soille2018dawos, url = {https://ec.europa.eu/eurostat/cros/system/files/dawos18_lecture.soille.jeodpp.pdf}, author = {Soille, P.}, title = {The Big Data Platform Initiative of the {EC} {J}oint {R}esearch {C}entre}, howpublished = {Presentation at the data analytics Workshop for official statistics (daWos)}, month = sep, year = {2018} } @Misc{ soille-demarchi2018dawos, url = {https://ec.europa.eu/eurostat/cros/system/files/dawos18_lecture.soille.jeodpp.pdf}, author = {Soille, P. and De Marchi, D.}, title = {Interactive Geospatial Data Analytics using {JupyterLab}}, howpublished = {Presentation at the data analytics Workshop for official statistics (daWos)}, month = sep, year = {2018} } @TechReport{ syrris-etal2018tr, author = {Syrris, V. and Pesek, O. and Burger, A. and Soille, P.}, title = {Assessing {GPU} performance by testing Deep Neural Networks on Tensorflow and {K}eras}, institution = {Joint Research Centre of the European Commission}, year = {2018}, number = {JRC114930} } @TechReport{ burger-kliment-hasenohr2018tr, author = {Burger, A. and Kliment, T. and Hasenohr, P.}, title = {{JEODPP} Infrastructure Evolution and Data Management}, institution = {Joint Research Centre of the European Commission}, year = {2018}, number = {JRC115192} } @TechReport{ kempeneers-etal2018tr-use-cases, author = {Kempeneers, P. and Syrris, V. and Rodriguez, D. and Marletta, L. and De Marchi, D. and Burger, A. and Soille, P.}, title = {Sandbox Computing Environment of the {JRC} Earth Observation Data and Processing Platform: 2018 Use-Case Report}, institution = {Joint Research Centre of the European Commission}, year = {2018}, number = {JRC116686} } @Article{ uhl-etal2018ijde, author = {Uhl, Johannes H. and Zoraghein, Hamidreza and Leyk, Stefan and Balk, Deborah and Corbane, Christina and Syrris, Vasileios and Florczyk, Aneta J.}, title = {Exposing the urban continuum: implications and cross-comparison from an interdisciplinary perspective}, journal = {International Journal of Digital Earth}, volume = {0}, number = {0}, pages = {1-23}, year = {2018}, doi = {10.1080/17538947.2018.1550120} } @InProceedings{ burger-etal2019cs3, author = {Burger, Armin amd Hasenohr, Paul and De Marchi, Davide and Soille, Pierre}, title = {Advanced geo-spatial data analysis with {J}upyter}, doi = {10.5281/zenodo.2545482}, booktitle = {Book of abstracts of CS3 2019 - Workshop on Cloud Storage Synchronization and Sharing Services}, year = {2019}, editor = {Chan, Belinda}, pages = {43}, publisher = {CERN} } @InProceedings{ burger2019eos, author = {Burger, A.}, title = {{EOS} as storage back-end for {JRC} scientific data processing}, url = {https://cds.cern.ch/record/2659480}, booktitle = {EOS Workshop}, year = {2019}, editor = {CERN}, month = feb } @Misc{ soille2019bids_slides, author = {Soille, P.}, title = {Big Data at JRC}, url = {https://az659834.vo.msecnd.net/eventsairwesteuprod/production-nikal-public/fad098b050c6446c8cd7056361c60892}, howpublished = {Presentation at the opening session of the 2019 Big Data from Space conference (BiDS'19)}, year = {2019}, month = feb } @InProceedings{ demarchi-soille2019bids_short, author = {De Marchi, D. and Soille, P.}, title = {Advances in interactive processing and visualisation with {J}upyter{L}ab on the {JRC} Big Data Platform ({JEODPP})}, pages = {45-48}, doi = {10.5281/zenodo.3239239}, booktitle = {Proc. of BiDS'19}, year = {2019} } @Misc{ demarchi-soille2019bids_slides, author = {De Marchi, D. and Soille, P.}, title = {Advances in interactive processing and visualisation with {J}upyter{L}ab on the {JRC} Big Data Platform ({JEODPP})}, url = {https://az659834.vo.msecnd.net/eventsairwesteuprod/production-nikal-public/e19a3c2756ab4b4aaa2f4be8bd71ff51}, howpublished = {Presentation at the 2019 Big Data from Space conference (BiDS'19)}, year = {2019}, month = feb } @InProceedings{ corbane-etal2019bids_short, author = {Corbane, C. and Panagiotis, P. and Kempeneers, P. and Pesaresi, M. and Rodriguez, D. and Syrris, V. and Soille, P.}, title = {Automatic image data analytics from a global {S}entinel-2 composite for the study of human settlements}, pages = {89-92}, url = {https://cidportal.jrc.ec.europa.eu/services/shared/pdfs/corbane-etal2019bids.pdf}, doi = {10.2760/848593}, booktitle = {Proc. of BiDS'19}, year = {2019} } @Misc{ corbane-etal2019bids_slides, author = {Corbane, C. and Panagiotis, P. and Kempeneers, P. and Pesaresi, M. and Rodriguez, D. and Syrris, V. and Soille, P.}, title = {Automatic image data analytics from a global {S}entinel-2 composite for the study of human settlements}, howpublished = {Presentation at the 2019 Big Data from Space conference (BiDS'19)}, url = {https://az659834.vo.msecnd.net/eventsairwesteuprod/production-nikal-public/da34c89c72a3409f8a7921b42217903b}, year = {2019}, month = feb } @InProceedings{ schramm-etal2019bids_short, author = {Schramm, Matthias and Pebesma, Edzer and Wagner, Wolfgang and Verbesselt, Jan and Dries, Jeroen and Briese, Christian and Jacob, Alexander and Mohr, Matthias and Neteler, Markus and Mistelbauer, Thomas and Miksa Tomasz and Gebbert, Sören and Gößwein, Bernhard and Kadunc, Miha and Kempeneers, Pieter and Gorelick, Noel}, title = {{openEO} ---{A} Standardised Connection to and between Earth Observation Service Providers}, pages = {229-232}, doi = {10.5281/zenodo.2601916}, booktitle = {Proc. of BiDS'19}, year = {2019} } @Proceedings{ soille-loekken-albani2019bids, title = {Proc. of the 2019 Conference on Big Data from Space (BiDS'19)}, year = {2019}, doi = {10.2760/848593}, editor = {Soille, P. and Loekken, S. and Albani, S.}, address = {Munich, Germany}, month = feb, organization = {ESA-JRC-SatCen}, publisher = {Publications Office of the European Union} } @InProceedings{ kempeneers-soille2019lps, author = {Kempeneers, P. and Soille. P.}, title = {Full resolution global {S}entinel-2 mosaics: an effective and efficient method based on quicklooks and cloud masks}, url = {}, booktitle = {Living Planet Symposium}, year = {2019}, number = {} } @InProceedings{ verheggen-etal2019lps, author = {Verheggen, A. and Janouskova, K. and Syrris, V. and Combal, B. and Hugh, E. and Achard, F.}, title = {Mapping {A}frican dry forests with {S}entinel 1 and 2 time series: a case study over {T}anzania}, url = {}, booktitle = {Living Planet Symposium}, year = {2019}, number = {} } @InProceedings{ edzer-etal2019egu, author = {Pebesma, Edzer and Wagner, Wolfgang and Soille, Pierre and Kadunc, Miha and Gorelick, Noel and Schramm, Matthias and Verbesselt, Jan and Reiche, Johannes and Mohr, Matthias and Dries, Jeroen and Jacob, Alexander and Neteler, Markus and Gebbert, Soeren and Briese, Christian and Kempeneers, Pieter}, title = {{openEO:} analyses Earth Observation data based on user-defined raster and vector data cube views}, url = {https://meetingorganizer.copernicus.org/EGU2019/EGU2019-9737.pdf}, booktitle = {Geophysical Research Abstracts}, year = {2019}, volume = {20}, number = {EGU2019-9737} } @Article{ syrris-etal2019rs, author = {Syrris, V. and Hasenohr, P. and Delipetrev, B. and Kotsev, A. and Soille, P.}, title = {Evaluation of the potential of convolutional neural networks and random forests for multi-class segmentation of {S}entinel-2 imagery}, journal = {Remote Sensing}, year = {2019}, doi = {10.3390/rs11080907}, url = {https://cidportal.jrc.ec.europa.eu/services/webview/jeodpp/ml-showcase/}, volume = {11}, number = {8}, pages = apr } @Article{ corbane-etal2019bed, title = {Automated global delineation of human settlements from 40 years of {L}andsat satellite data archive}, author = {Corbane, Christina and Pesaresi, Martino and Kemper, Thomas and Politis, Panagiotis and Florczyk, Aneta J. and Syrris, Vasileios and Melchiorri, Michele and Sabo, Filip and Soille, Pierre}, journal = {Big Earth Data}, year = {2019}, volume = {3}, number = {2}, pages = {140-169}, doi = {10.1080/20964471.2019.1625528} } @Article{ sabo-etal2019grsl, author = {Sabo, F. and Corbane, C. and Syrris, V. and Kemper, T. and Politis, P. and Pesaresi, M. and Soille, P. and Os\'e, K.}, title = {Application of the Symbolic Machine Learning to {C}opernicus {VHR} Imagery: The {E}uropean Settlement Map}, journal = {Geoscience and Remote Sensing Letters}, year = {2019}, optkey = {}, optvolume = {}, optnumber = {}, optpages = {}, optmonth = {}, optannote = {} } @TechReport{ kempeneers-soille2019s2l2amosaic, author = {Kempeneers, P. and Soille, P.}, title = {Global mosaic of Copernicus Sentinel-2 L2A data 2017}, institution = {Joint Research Centre of the European Commission}, year = {2019}, optdoi = {}, url = {} } @TechReport{ nativi-losada2019tr, author = {Anderberg, Amanda and Asturiol, Bofill David and Baldini, Gianmarco and Breyiannis, George and Cardona, Melisande and Castillo, Carlos and Charisi, Vasiliki and Checchi, Enrico and Christidis, Panayotis and Coisel, Iwen and Corban, Christina and Cotelo, Lema Jose Antonio and D'andrimont, Raphael and De, Prato Giuditta and Delipetrev, Blagoj and Devos, Wim and Dewandre, Nicole and Dimitrova, Tatyana and Dottori, Francesco and Duch, Brown Nestor and Enescu, Valentin and Ferrara, Pasquale and Fidalgo, Merino Raul and Gabrielli, Lorenzo and Galbally, Herrero Javier and Geneiatakis, Dimitrios and Giuliani, Raimondo and Gomez Gutierrez, Emilia and Gomez Losada, Alvaro and Hradec, Jiri and Iglesias Portela, Maria and Ignat, Camelia and Junklewitz, Henrik and Kalas, Milan and Kemper, Thomas and Kotsev, Alexander and Kreysa, Joachim and Lavaysse, Christophe and Lemoine, Guido and Lopez, Cobo Montserrat and Lorini, Valerio and Martens, Bertin and Miron, Marius and Nai, Fovino Igor and Nappo, Domenico and Natale, Fabrizio and Nativi, Stefano and Nukaj, Bledi and Pedone, Mauro and Perrotta, Domenico and Pesaresi, Martino and Petrillo, Mauro and Poulymenopoulou, Mikaela and Psyllos, Apostolos and Righi, Riccardo and Salamon, Peter and Samoili, Sofia and Sanchez Belenguer, Carlos and Sanchez, Martin Jose Ignacio and Sequeira, Vitor and Soille, Pierre and Spyratos, Spyridon and Steri, Gary and Tirelli, Daniel and Triaille, Jean-Paul and Tolan, Songul and Toreti, Andrea and Tsois, Aris and Vakalis, Ioannis and Van Der Velde, Marijn and Vespe, Michele and Wittwehr, Clemens}, title = {Artificial Intelligence at {JRC}}, institution = {Joint Research Centre of the European Commission}, year = {2019}, doi = {10.2760/705074} } jeolib-miallib-1.1.6/swig/python/packages/000077500000000000000000000000001467232417700204575ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/python/packages/miallib/000077500000000000000000000000001467232417700220705ustar00rootroot00000000000000jeolib-miallib-1.1.6/swig/python/packages/miallib/__init__.py000066400000000000000000000036601467232417700242060ustar00rootroot00000000000000#from miallib import * #from pointop_base import * # this makes miallib.arith available #import pointop_base # this makes miallib.pointop_base.arith available #from io_base import * # there is no imem (only imem_base) # this makes functions available both as miallib.copy_image # and miallib.imem_base.copy_image #from imem_base import * # # uncomment to make all base functions available at top level # from miallib import * # from convolve_base import * # from dem_base import * # from dist_base import * # from erodil_base import * # from format_base import * # from geodesy_base import * # from geometry_base import * # from hmt_base import * # from imem_base import * # from io_base import * # from label_base import * # from opclo_base import * # from pointop_base import * # from proj_base import * # from segment_base import * # from stats_base import * # # # # # uncomment to make all extended functions available at top level # from format import * # from geometry import * # from geodesy import * # from stats import * # from io import * # from pointop import * # from visu import * # from dist import * # packages with base only definitions from . import convolve_base from . import dem_base from . import dist_base from . import erodil_base from . import hmt_base from . import label_base from . import opclo_base from . import proj_base from . import segment_base # packages with base and extended definitions from . import format from . import geometry from . import geodesy from . import stats from . import io from . import pointop from . import visu from . import dist from . import miallib as base_functions # use . to secure that the local subpackage is imported # from .format import * # from .geodesy import * # from .geometry import * #from .io import * #import io # from .imstat import * # from .pointop import * # from .visu import * # __all__ = ['format', 'geodesy', 'geometry', 'io', # 'imstat', 'pointop', 'visu'] jeolib-miallib-1.1.6/swig/python/packages/miallib/dist.py000066400000000000000000000006231467232417700234060ustar00rootroot00000000000000from . import miallib as _miallib from .dist_base import * from . import imem_base as _imem_base def nd_sqedt(i0): i1 = _imem_base.copy_image(i0) sqedt(i1) return i1 def nd_geodist(mask, marker, graph): mask2 = _imem_base.copy_image(mask) out = geodist(mask2, marker, graph) if out==_miallib.NO_ERROR: return mask2 else: return 'nd_geodist(): error' jeolib-miallib-1.1.6/swig/python/packages/miallib/format.py000066400000000000000000000012741467232417700237360ustar00rootroot00000000000000 from . import miallib as _miallib from .format_base import * def d_touchar(i0): to_uchar(i0) return i0 def getpixmax(im): if (im.DataType==_miallib.t_UCHAR): return pow(2,8)-1 if (im.DataType==_miallib.t_USHORT): return pow(2,16)-1 if (im.DataType==_miallib.t_SHORT): return pow(2,15)-1 if (im.DataType==_miallib.t_UINT32): return pow(2,32)-1 if (im.DataType==_miallib.t_INT32): return pow(2,31)-1 if (im.DataType==_miallib.t_INT64): return pow(2,64)-1 if (im.DataType==_miallib.t_UINT64): return pow(2,63)-1 if (im.DataType==_miallib.t_DOUBLE): return _miallib.DOUBLE_MAX return None jeolib-miallib-1.1.6/swig/python/packages/miallib/geodesy.py000066400000000000000000000025271467232417700241070ustar00rootroot00000000000000#import miallib # this makes all geodesy_base functions available within miallib.geodesy # but also makes geodesy_base available as a subpackage from .geodesy_base import * from . import imem_base as _imem_base from . import geometry as _geometry from . import pointop as _pointop #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; # Geodesic transformations defined in python only #;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; def d_rdil(marker, mask, graph, flag): rdil(marker, mask, graph, flag) return marker def nd_rdil(marker, mask, graph, flag): i0=_imem_base.copy_image(marker) rdil(i0, mask, graph, flag) return i0 def d_rero(marker, mask, graph, flag=0): rero(marker, mask, graph, flag) return marker def nd_rero(marker, mask, graph, flag): i0=_imem_base.copy_image(marker) rdil(i0, mask, graph, flag) return i0 def d_rerodilp(marker, mask, graph, flag, version): rdil(marker, mask, graph, flag, version) return marker def nd_rerodilp(marker, mask, graph, flag, version): i0=_imem_base.copy_image(marker) rdil(i0, mask, graph, flag, version) return i0 def fillhole(im, graph=4): marker=_imem_base.create_image(im.DataType, im.nx, im.ny, im.nz) _pointop.d_blank(marker, 255.0) _geometry.d_framebox(marker, 2, 2, 2, 2, 0, 0, 0.0) return d_rero(marker, im, graph) jeolib-miallib-1.1.6/swig/python/packages/miallib/geometry.py000066400000000000000000000120611467232417700242750ustar00rootroot00000000000000from . import miallib as _miallib from .geometry_base import * from . import imem_base as _imem_base def d_framebox(i0, box, val): r=framebox(i0, box, val) if r==_miallib.NO_ERROR: return i0 else: return 'd_framebox(): invalid data type' def nd_framebox(i0, box, val): d_framebox(_imem_base.copy_image(i0), box, val) def d_subframebox(i0, box): subframebox(i0, box) return i0 def nd_subframebox(i0, box): d_subframebox(_imem_base.copy_image(i0), box) def d_addframebox(i0, box, val): addframebox(i0, box, val) return i0 def nd_addframebox(i0, box, val): d_addframebox(_imem_base.copy_image(i0), box, val) def d_imputintopgeo(im1, im2, op, geotifffn1, geotifffn2, multfactor=1): ulcx1=getulcx(geotifffn1) ulcy1=getulcy(geotifffn1) res1=multfactor*getscale(geotifffn1) ulcx2=getulcx(geotifffn2) ulcy2=getulcy(geotifffn2) res2=multfactor*getscale(geotifffn2) ox1 = ulcx1 * multfactor oy1 = ulcy1 * multfactor ox2 = ulcx2 * multfactor oy2 = ulcy2 * multfactor if res1 != res2: print('input images must have the same pixel size') return if int(ox2-ox1) != int((ox2-ox1)/res1)*res1: print('X-GLOUP THIS SHOULD NEVER HAPPEN') return else: print('X-FINE') if int(oy1-oy2) != int((oy1-oy2)/res1)*res1: print('Y-GLOUP THIS SHOULD NEVER HAPPEN') return else: print('Y-FINE') d_imputintop(im1, im2, int((ox2-ox1)/res1), int((oy1-oy2)/res1), 0, op) if (getepsg(geotifffn1) == 4326.0) and (ulcx1==-180.0): if (ulcx2+(getnx(geotifffn2)*res2)) > 180.0: d_imputintop(im1, im2, int(((ox2-ox1)/res1)-(360.0/res1)), int((oy1-oy2)/res1), 0, op) return im1 def setaxisparaml(x, nx1, nx2): l=0 # width of left border to trim r=0 # width of right border to trim inter=1 # intersection predicate if x<0: if nx2 <= abs(x): inter=0 else: l=abs(x) i=0 if (nx2-l) > nx1: r=(nx2-l)-nx1 elif x>=nx1: inter=0 else: i=x if (nx2+x)>nx1: r=nx2+x-nx1 if inter==1: return(i, l, r) # (defun setaxisparaml (x nx1 nx2) # (let ( # (i) ; actual UL coordinate after trimming # (l 0) ; width of left border to trim # (r 0) ; width of right border to trim # (int 1) ; intersection predicate # ) # (if (< x 0) # (progn # (if (<= nx2 (abs x)) # (setq int 0) # (progn # (setq l (abs x)) # (setq i 0) # (if (> (- nx2 l) # nx1) # (setq r (- (- nx2 # l) # nx1) # ) # () # ) # ) # ) # ) # (if (>= x nx1) # (setq int 0) # (progn # (setq i x) # (if (> (+ nx2 x) # nx1) # (setq r (- (+ nx2 x) # nx1) # ) # () # ) # ) # ) # ) # (if (= int 1) # (list i l r) # (print "warning: no intersection") # ) # ) # ) def d_imputintop(im1, im2, x, y, z, op): xaxisparaml = setaxisparaml(x, im1.nx, im2.nx) yaxisparaml = setaxisparaml(y, im1.ny, im2.ny) zaxisparaml = setaxisparaml(z, im1.nz, im2.nz) if xaxisparaml: if yaxisparaml: if zaxisparaml: imputop(im1, nd_subframebox(im2, \ xaxisparaml[0], xaxisparaml[1], \ yaxisparaml[0], yaxisparaml[1], \ zaxisparaml[0], zaxisparaml[1]), xaxisparaml[0], yaxisparaml[0], zaxisparaml[0], op) im1 im1 im1 im1 # (defun @imputintop (im1 im2 x y z op) # ; \lspfunction{@}{imputintop}{im1 im2 x y z op} # ; \param{im1}{an image node} # ; \param{im2}{an image node} # ; \param{x}{integer for x coordinate} # ; \param{y}{integer for y coordinate} # ; \param{z}{integer for z coordinate} # ; \param{op}{integer for operation type} # ; \return{im1} # ; \desc{all pixels of im2 falling within im1 are combined with those of im1 using point-wise operation op. Im2 is set at coordinates (x,y,z) assuming that (0,0,0) is the upper left pixel of im1. Available operation types are defined as global variables such as ADD_op, SUP_op, etc.} # ; \myseealso{} # ; \lspfile{\crtlspfile} # ; \example{}{} # (let ( # (xaxisparaml (setaxisparaml x (*getnx im1) (*getnx im2))) # (yaxisparaml (setaxisparaml y (*getny im1) (*getny im2))) # (zaxisparaml (setaxisparaml z (*getnz im1) (*getnz im2))) # ) # (if (listp xaxisparaml) # (if (listp yaxisparaml) # (if (listp zaxisparaml) # (@imputop im1 # (*subframebox im2 # (nth 1 xaxisparaml) # (nth 2 xaxisparaml) # (nth 1 yaxisparaml) # (nth 2 yaxisparaml) # (nth 1 zaxisparaml) # (nth 2 zaxisparaml) # ) # (nth 0 xaxisparaml) (nth 0 yaxisparaml) (nth 0 zaxisparaml) # op) # im1 # ) # im1 # ) # im1 # ) # ) # ) jeolib-miallib-1.1.6/swig/python/packages/miallib/io.py000066400000000000000000000040231467232417700230500ustar00rootroot00000000000000#import miallib # this makes all io_base functions available within miallib.io. e.g. miallib.io.read_image # but also makes io_base available as a subpackage: miallib.io_base.read_image. from .io_base import * # this makes imem__base functions available directly in this file, e.g., copy_image() # but it also makes all imem_base functions available directly in miallib.imem_base, # e.g., miallib.imem_base.copy_image # but also as miallib.imem_base in ipython #from imem_base import * # this makes imem_base functions available in this file, e.g., imem_base.copy_image() # but also as miallib.imem_base in ipython from . import imem_base as _imem_base def getnx(fn): gdi=GDALInfoJIP(fn) if gdi: return int(_imem_base.getpixval(gdi, 6)) return None def getny(fn): gdi=GDALInfoJIP(fn) if gdi: return int(_imem_base.getpixval(gdi, 7)) return None def getulcx(fn): gdi=GDALInfoJIP(fn) if gdi: return _imem_base.getpixval(gdi, 0) return None def getulcy(fn): gdi=GDALInfoJIP(fn) if gdi: return _imem_base.getpixval(gdi, 3) return None def getepsg(fn): gdi=GDALInfoJIP(fn) if gdi: return int(_imem_base.getpixval(gdi, 9)) return None def getscale(fn): gdi=GDALInfoJIP(fn) if gdi: return _imem_base.getpixval(gdi, 1) return None def MyGDALRead(fn, band_number=0): """Read a specific band_number from a file name Keyword arguments: fn -- string for file name with path band_number -- integer indicating band_number (default is 0) """ return GDALRead(fn, band_number, 0, 0, getnx(fn), getny(fn), getnx(fn), getny(fn)) def writeGeofnTiffOneStripPerLine(i0, fn, ref_fn): writeGeoTiffOneStripPerLine(i0, fn, getepsg(ref_fn), getulcx(ref_fn), getulcy(ref_fn), getscale(ref_fn), 1, 0, 0, 0, "") def writeMBGeofnTiffOneStripPerLine(imarray, n, fn, ref_fn): writeMBGeoTiffOneStripPerLine(rgb, n, fn, getepsg(ref_fn), getulcx(ref_fn), getulcy(ref_fn), getscale(ref_fn), 1, 0, 0, 0, "") jeolib-miallib-1.1.6/swig/python/packages/miallib/pointop.py000066400000000000000000000053271467232417700241410ustar00rootroot00000000000000# functions are destructive or non-destructive # destructive does not always exists (@function in lisp) # non-destructive always exists from . import miallib as _miallib #import pointop_base # we want pointop_base appear at the same level as the additional functions provided in this file. from .pointop_base import * from . import imem_base as _imem_base def arithNew(i0, i1, op, inplace=0): """Arithmetic operations between two input images. By default the operation is performed in place so that the first image holds the result of the opration once completed. :param i0: first image :param i1: second image :param op: integer for operation type :param inplace: 0 for in place (default), otherwise :returns: result of the operation (i.e., i0 if in place, a new image otherwise :rtype: an image """ if (inplace==0): arith(i0, i1, op) return i0 i2=_imem_base.copy_image(i0) arith(i2, i1, op) return i2 def d_arith(i0, i1, op): arith(i0, i1, op) return i0 def nd_arith(i0, i1, op): i2=_imem_base.copy_image(i0) arith(i2, i1, op) return i2 def d_imsqrt(i0): if imsqrt(i0)==_miallib.NO_ERROR: return i0 return _miallib.ERROR def nd_imsqrt(i0): i1=_imem_base.copy_image(i0) if imsqrt(i1)==_miallib.NO_ERROR: return i1 return _miallib.ERROR def d_thresh(i0,low,high,bg,fg): r=thresh(i0, low, high, bg, fg) if r==_miallib.NO_ERROR: return i0 else: return 'd_thresh(): invalid data type' def nd_thresh(i0,low,high,bg,fg): i1=_imem_base.copy_image(i0) return d_thresh(i1,low,high,bg,fg) def d_blank(i0,val): r=blank(i0, val) if r==_miallib.NO_ERROR: return i0 else: return 'd_blank(): invalid data type' def nd_blank(i0,val): i1=_imem_base.copy_image(i0) return d_blank(i1,val) def d_setlevel(i0,low,high,val): r= setlevel(i0, low, high, val) if r==_miallib.NO_ERROR: return i0 else: return 'd_setlevel(): invalid data type' def nd_setlevel(i0,low,high,val): i1=_imem_base.copy_image(i0) return d_setlevel(i1,low,val) # def setgtval(gt, val, type): # if type==_miallib.t_UCHAR: # gt.us_val=val # elif type==_miallib.t_USHORT: # gt.us_val=val # elif type==_miallib.t_INT32: # gt.i32_val=val # elif type==_miallib.t_UINT32: # gt.u32_val=val # elif type==_miallib.t_INT64: # gt.i64_val=val # elif type==_miallib.t_UINT64: # gt.u64_val=val # elif type==_miallib.t_FLOAT: # gt.f_val=val # elif type==_miallib.t_DOUBLE: # gt.d_val=val # else: # print('setgtval: invalid type provided:', type) jeolib-miallib-1.1.6/swig/python/packages/miallib/stats.py000066400000000000000000000047051467232417700236060ustar00rootroot00000000000000from . import pointop as _pointop from . import imem_base as _imem_base from . import format as _format from .stats_base import * def d_histostretch(im, percentageLow, percentageHigh, noData=None, minStretch=0, maxStretch=None): """Image enhancement based on histogram calculations (originally written in lisp, see @histostrech function) :param im: an image :param percentageLow: cut-off percentage from below :param percentageHigh: cut-off percentage from above :param noData: value or list of values to ignore during stretching, default is None :param minStretch: minimum output value (must be in range of underlying im data type), default is zero :param maxStretch: maximum output value (must be in range of underlying im data type), default will be the maximum value authorised by im data type :returns: im itself (destructive function) :rtype: IMAGE """ hst=histo1d(im) if (noData!=None): print("noData given") if isinstance(noData,list): for i in noData: _imem_base.setpixval(hst,i,0.0) else: _imem_base.setpixval(hst,noData,0.0) if (maxStretch==None): maxStretch=_format.getpixmax(im) for i in range(0,hst.nx): if (_imem_base.getpixval(hst, i) != 0): valmin=i # minimum image data value break for i in range(hst.nx-1, -1, -1): if (_imem_base.getpixval(hst, i) != 0): valmax=i # maximum image data value break volume(hst) vol=hst.vol # number of data values cutlow=round(vol*percentageLow/100.0) cuthigh=round(vol*(percentageHigh)/100.0) print("cutlow=%d" % cutlow) print("cuthigh=%d" % cuthigh) sum=0 for i in range(valmin, valmax+1): #print i sum=sum+_imem_base.getpixval(hst,i) #print sum if (sum>=cutlow): low=i break sum=0 for i in range(valmax, valmin-1, -1): sum=sum+_imem_base.getpixval(hst,i) if (sum>=cuthigh): high=i break print("valmin=%d" % valmin) print("valmax=%d" % valmax) print("low=%d" % low) print("high=%d" % high) print("minStretch=%d" % minStretch) print('maxStretch=%d' % maxStretch) _pointop.setlevel(im, float(valmin), float(low), float(low)) _pointop.setlevel(im, float(high), float(valmax), float(high)) _pointop.setrange(im, float(minStretch), float(maxStretch)) return im jeolib-miallib-1.1.6/swig/python/packages/miallib/visu.py000066400000000000000000000003761467232417700234360ustar00rootroot00000000000000#import miallib import os as _os from . import io as _io def xv(i0): _io.write_tiff(i0,"/tmp/toto.tif") _os.system("xv /tmp/toto.tif &") def imview(i0): _io.write_tiff(i0,"/tmp/toto.tif") _os.system("imview /tmp/toto.tif &") jeolib-miallib-1.1.6/swig/python/setup.py000066400000000000000000000107651467232417700204240ustar00rootroot00000000000000#!/usr/bin/env python """ setup.py file for SWIG miallib """ # see also https://docs.python.org/2/distutils/setupscript.html # see also https://docs.python.org/2/tutorial/modules.html # nur master.i ist zu editieren !!! from distutils.core import setup, Extension import re import os pyver = os.environ.get('PYVER', '3.6') # from setuptools import setup, find_packages if int(pyver[0]) == 3: swig_opts_val = ['-py3', '-v', '-Wall', '-I../include', '-outdir', './packages/miallib', '-I../include/python', '-I/usr/local/lib/python'+pyver+'/dist-packages/numpy/core/include', '-I/usr/local/lib/python'+pyver, '-I../../core/c', '-I../../core/build/doc/xml/', '-DMCISRG', '-DCLASSIF'] else: swig_opts_val = ['-v', '-Wall', '-I../include', '-outdir', './packages/miallib', '-I../include/python', '-I/usr/local/lib/python'+pyver+'/dist-packages/numpy/core/include', '-I/usr/local/lib/python'+pyver, '-I../../core/c', '-I../../core/build/doc/xml/', '-DMCISRG', '-DCLASSIF'] libraries_val = ['gdal', 'tiff', 'miallib_python'] library_dirs_val = ['../../core/build/lib', '/usr/lib/x86_64-linux-gnu', '/usr/local/lib'] include_dirs_val = ['/usr/local/lib/python'+pyver+'/dist-packages/numpy/core/include', '/usr/local/lib/python'+pyver, '../../core/c/'] define_macros_val = [('MCISRG', None), ('CLASSIF', None)] _miallib = Extension('_miallib', ['miallib.i'], swig_opts=swig_opts_val, libraries=libraries_val, library_dirs=library_dirs_val, include_dirs=include_dirs_val, define_macros=define_macros_val) ext_modules_list = ['convolve', 'dem', 'dist', 'erodil', 'format', 'geometry', 'geodesy', 'hmt', 'imem', 'io', 'label', 'opclo', 'pointop', 'proj', 'segment', 'stats'] def createExtension(str): return (Extension('_' + str + '_base', [str + '.i'], swig_opts=swig_opts_val, libraries=libraries_val, library_dirs=library_dirs_val, include_dirs=include_dirs_val, define_macros=define_macros_val)) modules_list = [] for idx in ext_modules_list: modules_list.append(createExtension(idx)) additional_py_modules = [] for idx in ext_modules_list: additional_py_modules.append('miallib/' + idx + '_base') # sos = [] # for idx in ext_modules_list: # sos.append('_' + idx + '_base.so') # create the interface file for each module for idx in ext_modules_list: if not(os.path.isfile('../include/' + idx + '.i')): with open("../include/master.i", "r") as sources: lines = sources.readlines() with open('../include/'+idx+'.i', "w") as sources: for line in lines: sources.write(re.sub('master', idx, line)) setup(name="miallib", version="0.1", author="Pierre Soille", author_email="Pierre.Soille@ec.europa.eu", copyright="(c) European Commission", license="(c) European Commission. Exact licence to be defined", description="""Python interface to miallib/jiplib thanks to SWIG""", long_description="""Python interface to miallib/jiplib thanks to SWIG: long description""", url="http://jeodpp.jrc.ec.europa.eu", ext_modules=[_miallib] + modules_list, package_dir={'': 'packages'}, packages=['miallib'], # #py_modules = ["miallib/miallib"], # py_modules = ['miallib/miallib'] + additional_py_modules + # ['miallib/format', # 'miallib/geometry', # 'miallib/geodesy', # 'miallib/stats', # 'miallib/io', # 'miallib/pointop', # 'miallib/visu'], #data_files=[('bitmaps', ['bm/b1.gif', 'bm/b2.gif'])], # package_data={'./build/lib.linux-x86_64-'+pyver+'/': ['_miallib.so']}, # + sos build_dir={'': './build'}, build_base={'': './build'} )