diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..4c257d5 --- /dev/null +++ b/Android.mk @@ -0,0 +1,530 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +#OpenCv +OPENCV_CAMERA_MODULES:=on +OPENCV_INSTALL_MODULES:=on + +include $(OPENCVSDK)/native/jni/OpenCV.mk + +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL + +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +include $(BUILD_SHARED_LIBRARY) + +# Makefile for building the Lane Detection native library with OpenCV + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Additional OpenCV modules (optional) +# Uncomment and modify as needed for your specific use case +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/imgproc/include +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/highgui/include + +# Define optimization flags (optional) +# Uncomment and modify to suit your performance needs +# LOCAL_CFLAGS += -O3 -fomit-frame-pointer -ffast-math + +# Define debugging flags (optional) +# Uncomment for debugging purposes +# LOCAL_CFLAGS += -g -DDEBUG + +# Define architecture-specific flags (optional) +# Uncomment and modify for specific architectures +# LOCAL_ARM_MODE := arm + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Custom pre-build actions +# This section can be used to perform tasks before the actual build starts +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + # For example: @echo "Checking dependencies..." + # You can use shell commands to prepare the build environment + # Example: @mkdir -p $(LOCAL_PATH)/build_output + +# Custom post-build actions +# This section can be used to perform tasks after the build completes +postbuild: + @echo "Build completed." + # Add your post-build commands here + # For example: @echo "Copying binaries to output directory..." + # You can use shell commands to finalize the build process + # Example: @cp $(LOCAL_PATH)/libs/$(LOCAL_MODULE).so $(LOCAL_PATH)/build_output/ +# Makefile for building the Lane Detection native library with OpenCV + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Additional OpenCV modules (optional) +# Uncomment and modify as needed for your specific use case +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/imgproc/include +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/highgui/include + +# Define optimization flags (optional) +# Uncomment and modify to suit your performance needs +# LOCAL_CFLAGS += -O3 -fomit-frame-pointer -ffast-math + +# Define debugging flags (optional) +# Uncomment for debugging purposes +# LOCAL_CFLAGS += -g -DDEBUG + +# Define architecture-specific flags (optional) +# Uncomment and modify for specific architectures +# LOCAL_ARM_MODE := arm + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Custom pre-build actions +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + # For example: @echo "Checking dependencies..." + # You can use shell commands to prepare the build environment + # Example: @mkdir -p $(LOCAL_PATH)/build_output + +# Custom post-build actions +postbuild: + @echo "Build completed." + # Add your post-build commands here + # For example: @echo "Copying binaries to output directory..." + # You can use shell commands to finalize the build process + # Example: @cp $(LOCAL_PATH)/libs/$(LOCAL_MODULE).so $(LOCAL_PATH)/build_output/ + +# Define build variables +BUILD_TYPE := debug + +# Conditional build steps +ifeq ($(BUILD_TYPE), debug) + LOCAL_CFLAGS += -g -O0 + @echo "Building in debug mode..." +else ifeq ($(BUILD_TYPE), release) + LOCAL_CFLAGS += -O3 + @echo "Building in release mode..." +endif + +# Handling multiple architectures +# Example for ARM and x86 (modify as needed) +ifeq ($(TARGET_ARCH), arm) + LOCAL_ARM_MODE := arm + @echo "Building for ARM architecture..." +else ifeq ($(TARGET_ARCH), x86) + LOCAL_LDFLAGS += -m32 + @echo "Building for x86 architecture..." +endif + +# Integrating custom modules or libraries +# Example of linking a custom library +CUSTOM_LIB_PATH := $(LOCAL_PATH)/libs/custom_lib +LOCAL_LDLIBS += -L$(CUSTOM_LIB_PATH) -lcustom + +# Including custom headers (optional) +# LOCAL_C_INCLUDES += $(LOCAL_PATH)/include + +# Target to clean build output +clean: + @echo "Cleaning build output..." + @rm -rf $(LOCAL_PATH)/build_output/* + +# Makefile for building the Lane Detection native library with OpenCV and curl + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL + +# Link curl library +LOCAL_LDLIBS += -lcurl + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Include directories for curl (modify path as needed) +LOCAL_C_INCLUDES += /usr/include/curl + +# Additional OpenCV modules (optional) +# Uncomment and modify as needed for your specific use case +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/imgproc/include +# LOCAL_C_INCLUDES += $(OPENCVSDK)/modules/highgui/include + +# Define optimization flags (optional) +# Uncomment and modify to suit your performance needs +# LOCAL_CFLAGS += -O3 -fomit-frame-pointer -ffast-math + +# Define debugging flags (optional) +# Uncomment for debugging purposes +# LOCAL_CFLAGS += -g -DDEBUG + +# Define architecture-specific flags (optional) +# Uncomment and modify for specific architectures +# LOCAL_ARM_MODE := arm + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Custom pre-build actions +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + # For example: @echo "Checking dependencies..." + # You can use shell commands to prepare the build environment + # Example: @mkdir -p $(LOCAL_PATH)/build_output + +# Custom post-build actions +postbuild: + @echo "Build completed." + # Add your post-build commands here + # For example: @echo "Copying binaries to output directory..." + # You can use shell commands to finalize the build process + # Example: @cp $(LOCAL_PATH)/libs/$(LOCAL_MODULE).so $(LOCAL_PATH)/build_output/ + +# Define build variables +BUILD_TYPE := debug + +# Conditional build steps +ifeq ($(BUILD_TYPE), debug) + LOCAL_CFLAGS += -g -O0 + @echo "Building in debug mode..." +else ifeq ($(BUILD_TYPE), release) + LOCAL_CFLAGS += -O3 + @echo "Building in release mode..." +endif + +# Handling multiple architectures +# Example for ARM and x86 (modify as needed) +ifeq ($(TARGET_ARCH), arm) + LOCAL_ARM_MODE := arm + @echo "Building for ARM architecture..." +else ifeq ($(TARGET_ARCH), x86) + LOCAL_LDFLAGS += -m32 + @echo "Building for x86 architecture..." +endif + +# Integrating custom modules or libraries +# Example of linking a custom library +CUSTOM_LIB_PATH := $(LOCAL_PATH)/libs/custom_lib +LOCAL_LDLIBS += -L$(CUSTOM_LIB_PATH) -lcustom + +# Including custom headers (optional) +# LOCAL_C_INCLUDES += $(LOCAL_PATH)/include + +# Target to clean build output +clean: + @echo "Cleaning build output..." + @rm -rf $(LOCAL_PATH)/build_output/* + # Makefile for building the Lane Detection native library with OpenCV and curl integration + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL + +# Link curl library +LOCAL_LDLIBS += -lcurl + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Include directories for curl (modify path as needed) +LOCAL_C_INCLUDES += /usr/include/curl + +# Define optimization flags (optional) +LOCAL_CFLAGS += -O2 + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Custom build target +build: prebuild $(LOCAL_MODULE) postbuild + +# Custom pre-build actions +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + +# Custom post-build actions +postbuild: + @echo "Build completed." + # Add your post-build commands here + +# Define clean target +clean: + @echo "Cleaning build output..." + @rm -rf $(LOCAL_PATH)/build_output/* +# Makefile for building the Lane Detection native library with OpenCV and curl integration + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL -lcurl + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Include directories for curl (modify path as needed) +LOCAL_C_INCLUDES += /usr/include/curl + +# Define optimization flags (optional) +LOCAL_CFLAGS += -O2 + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Custom build target +build: prebuild $(LOCAL_MODULE) postbuild + +# Custom pre-build actions +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + +# Custom post-build actions +postbuild: + @echo "Build completed." + # Add your post-build commands here + +# Define clean target +clean: + @echo "Cleaning build output..." + @rm -rf $(LOCAL_PATH)/build_output/* +# Android.mk for building the Lane Detection native library with OpenCV and curl integration + +# Define the local path +LOCAL_PATH := $(call my-dir) + +# Clear the variables to avoid conflicts +include $(CLEAR_VARS) + +# Define the module name and source files +LOCAL_MODULE := LaneDetectionNative +LOCAL_SRC_FILES := LaneDetector.cpp + +# OpenCV settings +OPENCV_CAMERA_MODULES := on +OPENCV_INSTALL_MODULES := on + +# Include the OpenCV makefile +include $(OPENCVSDK)/native/jni/OpenCV.mk + +# Include directories for curl (modify path as needed) +LOCAL_C_INCLUDES += /usr/include/curl + +# Compiler flags for C++ files +CPPFLAGS += -fno-strict-aliasing -mfpu=vfp -mfloat-abi=softfp +LOCAL_CPP_FEATURES := rtti exceptions + +# Link additional libraries +LOCAL_LDLIBS += -llog -ldl -landroid -lGLESv2 -lEGL -lcurl + +# Include the shared library build script +include $(BUILD_SHARED_LIBRARY) + +# Define optimization flags (optional) +LOCAL_CFLAGS += -O2 + +# Custom pre-build actions +.PHONY: prebuild +prebuild: + @echo "Starting pre-build tasks..." + # Add your pre-build commands here + +# Custom post-build actions +.PHONY: postbuild +postbuild: + @echo "Build completed." + # Add your post-build commands here + +# Define clean target +.PHONY: clean +clean: + @echo "Cleaning build output..." + @rm -rf $(LOCAL_PATH)/build_output/* + +// LaneDetector.cpp + +#include +#include +#include +#include +#include + +// Function to initialize and setup curl +void initializeCurl(CURL*& curl) { + curl = curl_easy_init(); + if (!curl) { + throw std::runtime_error("Failed to initialize curl"); + } +} + +// Function to establish token +std::string establishToken(const std::string& apiKey) { + // Placeholder for actual token establishment logic + return apiKey; +} + +// Function to handle API response +void handleApiResponse(const std::string& response) { + // Parse and process the response + std::cout << "API Response: " << response << std::endl; + + // Example: Save to a file (optional) + std::ofstream responseFile("vision_api_response.json"); + responseFile << response; + responseFile.close(); +} + +// Function to send image to Google Vision API +std::string sendImageToVisionAPI(CURL* curl, const std::string& imagePath, const std::string& token) { + // Read image and encode it to base64 (depends on the API requirements) + std::ifstream imageFile(imagePath, std::ios::binary); + std::ostringstream oss; + oss << imageFile.rdbuf(); + std::string imageBase64 = oss.str(); // Base64 encoding may be needed + + // Create JSON payload + std::string jsonPayload = "{\"requests\": [{\"image\": {\"content\": \"" + imageBase64 + "\"}, \"features\": [{\"type\": \"LABEL_DETECTION\"}]}]}"; + std::string url = "https://vision.googleapis.com/v1/images:annotate?key=" + token; + + std::string readBuffer; + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonPayload.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); + + CURLcode res = curl_easy_perform(curl); + if (res != CURLE_OK) { + fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); + } + + handleApiResponse(readBuffer); + return readBuffer; +} + +// Callback function for curl +static size_t WriteCallback(void* contents, size_t size, size_t nmemb, void* userp) { + ((std::string*)userp)->append((char*)contents, size * nmemb); + return size * nmemb; +} + +// Main function +int main() { + try { + CURL* curl; + initializeCurl(curl); + + std::string imagePath = "path/to/your/image.jpg"; + std::string apiKey = "your_google_vision_api_key"; + + // Establish the token + std::string token = establishToken(apiKey); + + // Send the image to the Vision API + sendImageToVisionAPI(curl, imagePath, token); + + // Cleanup curl + curl_easy_cleanup(curl); + } catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + + return 0; +} diff --git a/Application.mk b/Application.mk new file mode 100644 index 0000000..9b3b087 --- /dev/null +++ b/Application.mk @@ -0,0 +1,6 @@ +APP_STL := gnustl_static +APP_CPPFLAGS := -frtti -fexceptions +APP_ABI := all +APP_PLATFORM := android-18 +APP_OPTIM := release + diff --git a/LaneCalculations.cpp b/LaneCalculations.cpp new file mode 100644 index 0000000..950d5ab --- /dev/null +++ b/LaneCalculations.cpp @@ -0,0 +1,51 @@ + +#include "LaneCalculations.h" +#include +#include + +#include + +// Global static pointer used to ensure a single instance of the class. +LaneCalculations* LaneCalculations::m_pInstance = NULL; + +/** This function is called to create an instance of the class. + Calling the constructor publicly is not allowed. The constructor + is private and is only called by this Instance function. +*/ + +LaneCalculations* LaneCalculations::Instance() +{ + if (!m_pInstance) // Only allow one instance of class to be generated. + m_pInstance = new LaneCalculations; + + return m_pInstance; +} + + +double LaneCalculations::calculateMeanLateralPosition() +{ + return LaneCalculations::Instance()->sumLateralPosition/LaneCalculations::Instance()->countLateralPosition; + +} + +double LaneCalculations::calculateSDLP() +{ + double mean = calculateMeanLateralPosition(); + + double sumOfVariance = 0; + for(int i=0; i< LaneCalculations::Instance()->countLateralPosition; i++) + { + double temp1 = (LaneCalculations::Instance()->arrayLateralPosition[i] - mean) * (LaneCalculations::Instance()->arrayLateralPosition[i] - mean); + sumOfVariance += temp1; + + + } + + double variance = sumOfVariance/LaneCalculations::Instance()->countLateralPosition; + double sdlp = sqrt(variance); //dividing to calculate sdlp with respect to single lane + sdlp = floor(sdlp*100 + 0.5)/100; //rounding off to 2 d.p + + + return sdlp; +} + diff --git a/LaneCalculations.h b/LaneCalculations.h new file mode 100644 index 0000000..58c9259 --- /dev/null +++ b/LaneCalculations.h @@ -0,0 +1,66 @@ +/*------------------------------------------------------------------------------------------*\ +Logging lane metrics to help in understanding driver's behavior aka SDLP + +\*------------------------------------------------------------------------------------------*/ + +//#if !defined LINEF +//#define LINEF + +#include +#include + +#include + +#define PI 3.1415926 + +using namespace cv; +using namespace std; + +class LaneCalculations { + + private: + + LaneCalculations()//:sumLateralPosition(0), meanLateralPosition(0), countLateralPosition(0) + { + sumLateralPosition = 0; + meanLateralPosition = 0; + countLateralPosition = 0; + arrayLateralPosition = new double[50000]; + __android_log_print(ANDROID_LOG_ERROR, "LANE Calculations", "Constructur : %s", "Yes called"); + + }; + + LaneCalculations(LaneCalculations const&){}; + LaneCalculations& operator = (LaneCalculations const&){}; + static LaneCalculations* m_pInstance; + + + + // LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.) {} + + + public : + + //Mean Lateral Position value + double sumLateralPosition; + double meanLateralPosition; + int countLateralPosition; + + //Standard Deviation of Lateral Position (SDLP) + double* arrayLateralPosition; + + static LaneCalculations* Instance(); + + double calculateMeanLateralPosition(); + double calculateSDLP(); + + + + + + + + +}; + +//#endif diff --git a/LaneDetector.cpp b/LaneDetector.cpp new file mode 100644 index 0000000..1ba67c3 --- /dev/null +++ b/LaneDetector.cpp @@ -0,0 +1,953 @@ + +/** + * + * @author Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * + * + * contains code taken from: + * + * "Lane detection using OpenCV" + * https://github.com/jdorweiler/lane-detection + * Acknowledgments: jdorweiler + * Contact: jason@transistor.io + */ + + +#include +#include "lane_detector.h" +#include +#include + +#include +#include +#include + + +#include +#include +#include + +#include "linefinder.h" +#include "lanemetrics.h" + +#include + +#define PI 3.1415926 + +using namespace std; +using namespace cv; + + +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + + + //tried using VideoCapture but didn't work and getting no access to camera. reason is ndk doesn't allow to access camera in this native way like on desktop. + //somehow it is also not recommended + + //__android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "start mainDelegate"); + + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + //////reducing the image size//// + Mat image; + resize(imageOrig, image, Size(),0.25,0.25, cv::INTER_LINEAR); //to reduce it to quarter of size + + + int houghVote = houghValue; + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "hough value : %d", houghVote); + + + bool showSteps = false; //if set to true it shows multiple windows of intermediate steps + + + //double dWidth = cap.get(CV_CAP_PROP_FRAME_WIDTH); //get the width of frames of the video + //double dHeight = cap.get(CV_CAP_PROP_FRAME_HEIGHT); //get the height of frames of the video + + //cout << "Frame Size = " << dWidth << "x" << dHeight << endl; + + + if (image.empty()) + { + //break; + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + + exit(0); + } + + Mat gray; + cvtColor(image,gray,CV_RGB2GRAY); //convert image to grayscale + vector codes; + Mat corners; + findDataMatrix(gray, codes, corners); + drawDataMatrixCodes(image, codes, corners); + + /*ROI returns a matrix that is pointing to the ROI of the original image, located at the place specified by the rectangle. + so imageROI is really the Region of Interest (or subimage/submatrix) of the original image "image". + If you modify imageROI it will consequently modify the original, larger matrix. + Rect region_of_interest = Rect(x, y, w, h); current parameters try to take the lower half of the image on vertical frame*/ + + Rect roi(0,image.cols/3,image.cols-1,image.rows - image.cols/3);// set the ROI (region of interest) for the image + //Rect roi(0,image.cols/2,image.cols-1,image.rows - image.cols/2);// set the ROI (region of interest) for the image + + Mat imgROI = image(roi); + + // Display the image + if(showSteps){ + + namedWindow("Original Image"); + imshow("Original Image",imgROI); + imwrite("original.bmp", imgROI); + } + + /* Canny Edge Detector algorithm : canny (source image, edge output image, first threshold for the hysteresis procedure, + , second threshold for the hysteresis procedure, apersturesize i.e set to be 3 by default , L2gradient ) + threshold2 is recommended to be 3 times to threshold1 */ + + Mat contours; + Canny(imgROI,contours, 80,250,3); //50, 150,3); //in original code => 50,250); + + /* Thresholding is to differentiate the pixels we are interested in from the rest */ + Mat contoursInv; + threshold(contours,contoursInv,128,255,THRESH_BINARY_INV); + + // Display Canny image + if(showSteps){ + namedWindow("Contours"); + imshow("Contours1",contoursInv); + imwrite("contours.bmp", contoursInv); + } + + /* + Hough tranform for line detection with feedback + Increase by 25 for the next frame if we found some lines. + This is so we don't miss other lines that may crop up in the next frame + but at the same time we don't want to start the feed back loop from scratch. + */ + + + vector lines; + if (houghVote < 1 or lines.size() > 2){ // we lost all lines. reset + houghVote = houghValue; //previously it was set to 200 always + } + else{ houghVote += 25;} + + //ensuring lines size is 5 + while(lines.size() < 5 && houghVote > 0){ + HoughLines(contours,lines,1,PI/180, houghVote); + houghVote -= 5; + } + + //cout << houghVote << "\n"; + Mat result(imgROI.size(),CV_8U,Scalar(255)); + imgROI.copyTo(result); + + + + + // Draw the lines + vector::const_iterator it= lines.begin(); + Mat hough(imgROI.size(),CV_8U,Scalar(0)); + + + + while (it != lines.end()) + { + + //__android_log_print(ANDROID_LOG_INFO, "LANEDETECTOR++", "%s", "while of lines"); + + float rho= (*it)[0]; // first element is distance rho + float theta= (*it)[1]; // second element is angle theta + + // filter to remove vertical and horizontal lines + //if(theta is between 5 degrees and 84 degrees) or if(theta is between 95 degrees and 180 degrees ) + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) + { + // point of intersection of the line with first row + Point pt1(rho/cos(theta),0);//y = 0 + + // point of intersection of the line with last row + Point pt2((rho-result.rows*sin(theta))/cos(theta),result.rows);//y = row count + + + //This draws lines but without ends and in shape of X + line( hough, pt1, pt2, Scalar(255), 10); //this is working and shows red lines of thickness 10 + + + + } + + // cout << "line: (" << rho << "," << theta << ")\n"; + ++it; + } + + // Display the detected line image + if(showSteps) + { + namedWindow("Detected Lines with Hough"); + imshow("Detected Lines with Hough",result); + imwrite("hough.bmp", result); + } + + + // Create LineFinder instance + LineFinder ld; + + // Set probabilistic Hough parameters + ld.setLineLengthAndGap(60,10); + ld.setMinVote(4); + + // Detect lines + vector li= ld.findLines(contours); //applying probablity hough transform + + Mat houghP(imgROI.size(),CV_8U,Scalar(0)); + ld.setShift(0); + ld.drawDetectedLines(houghP); + //cout << "First Hough" << "\n"; + + if(showSteps){ + namedWindow("Detected Lines with HoughP"); + imshow("Detected Lines with HoughP", houghP); + imwrite("houghP.bmp", houghP); + } + + // bitwise AND of the two hough images. + //1) Normal Hough -> without end points 2) Probabilistic Hough -> with end points + + bitwise_and(houghP,hough,houghP); + Mat houghPinv(imgROI.size(),CV_8U,Scalar(0)); + Mat dst(imgROI.size(),CV_8U,Scalar(0)); + threshold(houghP,houghPinv,150,255,THRESH_BINARY_INV); // threshold and invert to black lines + + if(showSteps){ + namedWindow("Detected Lines with Bitwise"); + imshow("Detected Lines with Bitwise", houghPinv); + } + + + Canny(houghPinv,contours, 100,350);//100,150); //100,350); + li= ld.findLines(contours); + + // Display Canny image + if(showSteps){ + namedWindow("Contours"); + imshow("Contours2",contours); + imwrite("contours.bmp", contoursInv); + } + + // Set probabilistic Hough parameters + //These parameters set min and max values. If you set minvote as 100 then even if you set 60 from slider, it won't + //show any lines + + ld.setLineLengthAndGap(5,2); //5,2 original + ld.setMinVote(1); //1 original + + ld.setShift(image.cols/3); + ld.drawDetectedLines(image); + + + + + //to show the number of line segments found in a frame + //putText(image, stream.str(), Point(10,image.rows-10), 4, 1, Scalar(0,255,255),0); + + + lines.clear(); + + //Hough Processing ends here + + + + resize(image, image, Size(),4,4, cv::INTER_LINEAR); + output = image; + + //__android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "end mainDelegate"); + +}/** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +}/** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +} + +/** + * Additional Functions (to be implemented or integrated): + * - findDataMatrix: Detects data matrix codes in the image. + * - drawDataMatrixCodes: Draws detected data matrix codes on the image. + * - Lane Metrics Calculation: Compute lane curvature, lane departure warnings, etc. + * - JNI Integration: Ensure seamless integration with Android's native environment using JNI. + * - Error Handling: Implement robust error handling for edge cases and unexpected inputs. + * - Performance Optimization: Profile and optimize critical sections of the code for real-time performance. + * - Probabilistic Hough Transform: Use HoughLinesP for more accurate and detailed line detection. + * - Visualization and Debugging: Enable or disable visualization steps for debugging and development. + * - Integration with Android Camera: Implement camera access and real-time lane detection on Android devices. + */ +/** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +} + +/** + * Additional Functions (to be implemented or integrated): + * - findDataMatrix: Detects data matrix codes in the image. + * - drawDataMatrixCodes: Draws detected data matrix codes on the image. + * - Lane Metrics Calculation: Compute lane curvature, lane departure warnings, etc. + * - JNI Integration: Ensure seamless integration with Android's native environment using JNI. + * - Error Handling: Implement robust error handling for edge cases and unexpected inputs. + * - Performance Optimization: Profile and optimize critical sections of the code for real-time performance. + * - Probabilistic Hough Transform: Use HoughLinesP for more accurate and detailed line detection. + * - Visualization and Debugging: Enable or disable visualization steps for debugging and development. + * - Integration with Android Camera: Implement camera access and real-time lane detection on Android devices. + */ + +/** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +} + +/** + * Additional Functions (to be implemented or integrated): + * - findDataMatrix: Detects data matrix codes in the image. + * - drawDataMatrixCodes: Draws detected data matrix codes on the image. + * - Lane Metrics Calculation: Compute lane curvature, lane departure warnings, etc. + * - JNI Integration: Ensure seamless integration with Android's native environment using JNI. + * - Error Handling: Implement robust error handling for edge cases and unexpected inputs. + * - Performance Optimization: Profile and optimize critical sections of the code for real-time performance. + * - Probabilistic Hough Transform: Use HoughLinesP for more accurate and detailed line detection. + * - Visualization and Debugging: Enable or disable visualization steps for debugging and development. + * - Integration with Android Camera: Implement camera access and real-time lane detection on Android devices. + */ +/** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +} + +/** + * Additional Functions (to be implemented or integrated): + * - findDataMatrix: Detects data matrix codes in the image. + * - drawDataMatrixCodes: Draws detected data matrix codes on the image. + * - Lane Metrics Calculation: Compute lane curvature, lane departure warnings, etc. + * - JNI Integration: Ensure seamless integration with Android's native environment using JNI. + * - Error Handling: Implement robust error handling for edge cases and unexpected inputs. + * - Performance Optimization: Profile and optimize critical sections of the code for real-time performance. + * - Probabilistic Hough Transform: Use HoughLinesP for more accurate and detailed line detection. + * - Visualization and Debugging: Enable or disable visualization steps for debugging and development. + * - Integration with Android Camera: Implement camera access and real-time lane detection on Android devices. + *//** + * Lane Detection using OpenCV for Android + * + * Author: Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * Original Code Source: https://github.com/jdorweiler/lane-detection + * Acknowledgments: Jason Dorweiler (jdorweiler) + */ + +#include +#include +#include +#include +#include + +using namespace std; +using namespace cv; + +#define PI 3.1415926 + +/** + * JNI method to perform lane detection and processing on an input image. + * This method is called from Java code. + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue) +{ + // Convert jlong input parameters to OpenCV Mats + Mat& imageOrig = *(Mat*)in; + Mat& output = *(Mat*)out; + + // Resize the input image to reduce processing load + Mat image; + resize(imageOrig, image, Size(), 0.25, 0.25, cv::INTER_LINEAR); + + // Initialize parameters + int houghVote = houghValue; + bool showSteps = false; // Set to true to show intermediate steps + + // Check if the image is empty + if (image.empty()) { + __android_log_print(ANDROID_LOG_ERROR, "LANEDETECTOR++", "%s", "Cannot access the camera"); + exit(0); + } + + // Convert the image to grayscale + Mat gray; + cvtColor(image, gray, CV_RGB2GRAY); + + // Perform data matrix detection (if implemented) + // Example functions: findDataMatrix(gray, codes, corners); + // drawDataMatrixCodes(image, codes, corners); + + // Define Region of Interest (ROI) for lane detection + Rect roi(0, image.cols / 3, image.cols - 1, image.rows - image.cols / 3); + Mat imgROI = image(roi); + + // Display the original image (if showSteps is enabled) + if(showSteps) { + namedWindow("Original Image"); + imshow("Original Image", imgROI); + } + + // Perform Canny edge detection on the ROI + Mat contours; + Canny(imgROI, contours, 80, 250, 3); // Adjust thresholds as needed + + // Display the Canny edge image (if showSteps is enabled) + if(showSteps) { + namedWindow("Canny Edges"); + imshow("Canny Edges", contours); + } + + // Perform Hough Line Transform to detect lines in the image + vector lines; + HoughLines(contours, lines, 1, PI/180, houghVote); + + // Draw detected lines on a blank image + Mat result(imgROI.size(), CV_8U, Scalar(255)); + imgROI.copyTo(result); + + // Iterate through detected lines and filter out non-vertical and non-horizontal lines + for(auto it = lines.begin(); it != lines.end(); ++it) { + float rho = (*it)[0]; + float theta = (*it)[1]; + + if((theta > 0.09 && theta < 1.48) || (theta < 3.14 && theta > 1.66)) { + Point pt1(rho / cos(theta), 0); + Point pt2((rho - result.rows * sin(theta)) / cos(theta), result.rows); + line(result, pt1, pt2, Scalar(255), 10); // Draw lines on the result image + } + } + + // Display the image with detected lines (if showSteps is enabled) + if(showSteps) { + namedWindow("Detected Lines"); + imshow("Detected Lines", result); + } + + // Resize the final processed image before outputting + resize(image, image, Size(), 4, 4, cv::INTER_LINEAR); + output = image; +} + +/** + * Additional Functions (to be implemented or integrated): + * - findDataMatrix: Detects data matrix codes in the image. + * - drawDataMatrixCodes: Draws detected data matrix codes on the image. + * - Lane Metrics Calculation: Compute lane curvature, lane departure warnings, etc. + * - JNI Integration: Ensure seamless integration with Android's native environment using JNI. + * - Error Handling: Implement robust error handling for edge cases and unexpected inputs. + * - Performance Optimization: Profile and optimize critical sections of the code for real-time performance. + * - Probabilistic Hough Transform: Use HoughLinesP for more accurate and detailed line detection. + * - Visualization and Debugging: Enable or disable visualization steps for debugging and development. + * - Integration with Android Camera: Implement camera access and real-time lane detection on Android devices. + */ + + + + + + + + + + diff --git a/lane_detector.h b/lane_detector.h new file mode 100644 index 0000000..0a900eb --- /dev/null +++ b/lane_detector.h @@ -0,0 +1,24 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class tum_andrive_Andrive */ + + +#ifndef _Included_tum_andrive_LaneDetection_LaneDetector +#define _Included_tum_andrive_LaneDetection_LaneDetector +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: tum_andrive_lanedetection_LaneDetector + * Method: mainDelegate + * Signature: (JJ)V + */ + +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_LaneDetector_mainDelegate + (JNIEnv *env, jobject obj, jlong in, jlong out, jint houghValue); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/lane_test.h b/lane_test.h new file mode 100644 index 0000000..a0f71fb --- /dev/null +++ b/lane_test.h @@ -0,0 +1,24 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class tum_andrive_Andrive */ + +#ifndef _Included_tum_andrive_LaneDetection_TestMain +#define _Included_tum_andrive_LaneDetection_TestMain +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: tum_andrive_lanedetection_TestMain + * Method: nativeThreshold + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_TestMain_nativeThreshold + (JNIEnv *, jobject, jlong, jlong); + +JNIEXPORT void JNICALL Java_tum_andrive_lanedetection_TestMain_nativeCannyEdge + (JNIEnv *, jobject, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/lanemetrics.h b/lanemetrics.h new file mode 100644 index 0000000..ae05a4d --- /dev/null +++ b/lanemetrics.h @@ -0,0 +1,55 @@ +/** + * Logging lane metrics to help in understanding driver's behavior aka SDLP + */ + + + +#if !defined LINEF +#define LINEF + +#include +#include + +#include + +#define PI 3.1415926 + +using namespace cv; +using namespace std; + +class LaneMetrics { + + private: + + + //Mean Lateral Position value + static double sumLateralPosition; + static double meanLateralPosition; + static int countLateralPosition; + + //Standard Deviation of Lateral Position (SDLP) + static double* arrayLateralPosition; + + LaneMetrics() : sumLater; + // LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.) {} + + + public : + + static LaneMetrics& instance() + { + static LaneMetrics INSTANCE; + return INSTANCE; + } + + static getSumLaterationPosition + { + return sumLateralPosition; + } + + + + +}; + +#endif diff --git a/libLaneDetectionNative.so b/libLaneDetectionNative.so new file mode 100644 index 0000000..40919d3 Binary files /dev/null and b/libLaneDetectionNative.so differ diff --git a/libnative_camera_r2.2.0.so b/libnative_camera_r2.2.0.so new file mode 100644 index 0000000..f62e596 Binary files /dev/null and b/libnative_camera_r2.2.0.so differ diff --git a/libnative_camera_r2.3.3.so b/libnative_camera_r2.3.3.so new file mode 100644 index 0000000..c0237c1 Binary files /dev/null and b/libnative_camera_r2.3.3.so differ diff --git a/libnative_camera_r3.0.1.so b/libnative_camera_r3.0.1.so new file mode 100644 index 0000000..2c235d8 Binary files /dev/null and b/libnative_camera_r3.0.1.so differ diff --git a/libnative_camera_r4.0.0.so b/libnative_camera_r4.0.0.so new file mode 100644 index 0000000..4872588 Binary files /dev/null and b/libnative_camera_r4.0.0.so differ diff --git a/libnative_camera_r4.0.3.so b/libnative_camera_r4.0.3.so new file mode 100644 index 0000000..169d97e Binary files /dev/null and b/libnative_camera_r4.0.3.so differ diff --git a/libnative_camera_r4.1.1.so b/libnative_camera_r4.1.1.so new file mode 100644 index 0000000..bdd09fb Binary files /dev/null and b/libnative_camera_r4.1.1.so differ diff --git a/libnative_camera_r4.2.0.so b/libnative_camera_r4.2.0.so new file mode 100644 index 0000000..74bfdea Binary files /dev/null and b/libnative_camera_r4.2.0.so differ diff --git a/libopencv_java.so b/libopencv_java.so new file mode 100644 index 0000000..d048d87 Binary files /dev/null and b/libopencv_java.so differ diff --git a/linefinder.h b/linefinder.h new file mode 100644 index 0000000..3bb30ce --- /dev/null +++ b/linefinder.h @@ -0,0 +1,293 @@ + +/** + * + * @author Wahib-Ul-Haq, wahib.tech@gmail.com, 2014 + * + * + * contains code taken from: + * + * "Lane detection using OpenCV" + * https://github.com/jdorweiler/lane-detection + * Acknowledgments: jdorweiler + * Contact: jason@transistor.io + */ + +#if !defined LINEF +#define LINEF + +#include +#include + +#include +#include "LaneCalculations.cpp" +#include +#include + +#define PI 3.1415926 + +using namespace cv; +using namespace std; + +class LineFinder { + + private: + + // original image + Mat img; + + // vector containing the end points + // of the detected lines + vector lines; + + // accumulator resolution parameters + double deltaRho; + double deltaTheta; + + // minimum number of votes that a line must receive before being considered. + //The minimum number of intersections to “detect” a line + int minVote; + + // min length for a line + double minLength; + + // max allowed gap along the line + double maxGap; + + // distance to shift the drawn lines down when using a ROI + int shift; + + + + + public: + + // Default accumulator resolution is 1 pixel by 1 degree + // no gap, no mimimum length + LineFinder() : deltaRho(1), deltaTheta(PI/180), minVote(10), minLength(0.), maxGap(0.){} + + + + // Set the resolution of the accumulator + void setAccResolution(double dRho, double dTheta) { + + deltaRho= dRho; + deltaTheta= dTheta; + } + + // Set the minimum number of votes + void setMinVote(int minv) { + + minVote= minv; + } + + // Set line length and gap + void setLineLengthAndGap(double length, double gap) { + + minLength= length; + maxGap= gap; + } + + // set image shift + void setShift(int imgShift) { + + shift = imgShift; + } + + // Apply probabilistic Hough Transform + vector findLines(Mat& binary) { + + lines.clear(); + HoughLinesP(binary,lines,deltaRho,deltaTheta,minVote, minLength, maxGap); + + return lines; + } + + // Draw the detected lines on an image + void drawDetectedLines(Mat &image, Scalar color=Scalar(255)) { + + // Draw the lines + vector::const_iterator it2= lines.begin(); + + + + while (it2!=lines.end()) { + + Point pt1((*it2)[0],(*it2)[1]+shift); //end coordinate + Point pt2((*it2)[2],(*it2)[3]+shift); //start coordinate + + + //This is to draw the line with end points + line( image, pt1, pt2, color, 10 ); + //cout << " HoughP line: ("<< pt1 <<"," << pt2 << ")\n"; + + ///This chunk of code is commented to disable SDLP calculation and display of its values/// + + /* + int Houghpt2x = (*it2)[2]; + + //__android_log_print(ANDROID_LOG_ERROR, "HoughP line point 2", "Lane Type: %s, Value: %d", "Left Most Lane", Houghpt2x); + + int laneStatus = -1; + stringstream stream; + + + if(Houghpt2x >= 100 && Houghpt2x < 180 ) + { + laneStatus = 3; + __android_log_print(ANDROID_LOG_ERROR, "HoughP line point 2", "Lane Type: %s, Value: %d", "Left Lane", Houghpt2x); + stream << "Lane Status : " << "Left lane"; + + } + else if(Houghpt2x >= 180 && Houghpt2x <= 220 ) + { + laneStatus = 2; + __android_log_print(ANDROID_LOG_ERROR, "HoughP line point 2", "Lane Type: %s, Value: %d", "Switching ..", Houghpt2x); + stream << "Lane Status : " << "Switching .."; + + } + else if(Houghpt2x > 220 && Houghpt2x <= 450 ) + { + laneStatus = 1; + __android_log_print(ANDROID_LOG_ERROR, "HoughP line point 2", "Lane Type: %s, Value : %d", "Right Lane", Houghpt2x); + stream << "Lane Status : " << "Right lane"; + + } + + //int LateralPosition = Houghpt2x - 300 - 75; + //average width of car is 1.8 m + //average width of double lane road is 3.3 * 2 = 6.6 m + + //e.g 450 x value = 1.65 lateral position value + //e.g 350 x value = 1.89 + //scaling has 0 at left most that is the 0 for x coordinate as well + + //average vehicle width considered is 152 cm or 1.52 m and fixed lane width is used as 365 cm or 3.65 m + + double singleLaneWidth = 3.65; double avgCarWidth = 1.52; + int lowerBound = 100; int upperBound = 450; //range of x coordinate of Hought Point + double bestLateralPosition = avgCarWidth/2 + (((singleLaneWidth/2) - avgCarWidth)/2); // 0.915 - single lane //1.65 - when 2 lanes were considered + + + //x coordinate of Hough point is inverseley proportional to lateral position + double k = upperBound * bestLateralPosition; + double lateralPosition = 0; + if(Houghpt2x > 450) + lateralPosition = bestLateralPosition; + else if(Houghpt2x < 100) + lateralPosition = singleLaneWidth; + else + lateralPosition = k / Houghpt2x; + + + //preparing for SDLP + if(lateralPosition > 0) + { + //calculating lateral position value for each instance + lateralPosition = floor(lateralPosition*100 + 0.5)/100; //rounding off to 2 d.p + + //rounding off to 2 d.p + + + + //sumLateralPosition += lateralPosition; + //arrayLateralPosition[countLateralPosition] = lateralPosition; + //++countLateralPosition; + + LaneCalculations::Instance()->sumLateralPosition += lateralPosition; + LaneCalculations::Instance()->arrayLateralPosition[LaneCalculations::Instance()->countLateralPosition] = lateralPosition; + ++LaneCalculations::Instance()->countLateralPosition; + + __android_log_print(ANDROID_LOG_ERROR, "Line Finder", "count: %d", LaneCalculations::Instance()->countLateralPosition); + + + //displaying output + stringstream stream1; + stream1 << "Lateral position : " << setprecision(3) << lateralPosition; + __android_log_print(ANDROID_LOG_ERROR, "Line Finder", "Lateral Position: %f", lateralPosition); + + //displaying values on screen + putText(image, stream1.str(), Point(50,image.rows-70), 1, 1, Scalar(0,255,255),0); //lateral position + putText(image, stream.str(), Point(50,image.rows-30), 1, 1, Scalar(0,255,255),0); //lane status + + + //displaying sdlp value which is in m. ideal is somewhere around 0.30 m for one lane. This SDLP shows value + //after considerign 2 lanes -> 6.6 m + if(LaneCalculations::Instance()->countLateralPosition >= 1000) + { + __android_log_print(ANDROID_LOG_ERROR, "Line Finder", "SDLP: %f", LaneCalculations::Instance()->calculateSDLP()); + stringstream stream2; + stream2 << setprecision(3) << "SDLP : " << LaneCalculations::Instance()->calculateSDLP(); + putText(image, stream2.str(), Point(50,image.rows-110), 1, 1, Scalar(0,255,255),0); + } + + + + + + + } + + */ + + + ++it2; + } + } + + + // Eliminates lines that do not have an orientation equals to + // the ones specified in the input matrix of orientations + // At least the given percentage of pixels on the line must + // be within plus or minus delta of the corresponding orientation + vector removeLinesOfInconsistentOrientations( + const Mat &orientations, double percentage, double delta) { + + vector::iterator it= lines.begin(); + + // check all lines + while (it!=lines.end()) { + + // end points + int x1= (*it)[0]; + int y1= (*it)[1]; + int x2= (*it)[2]; + int y2= (*it)[3]; + + // line orientation + 90o to get the parallel line + double ori1= atan2(static_cast(y1-y2),static_cast(x1-x2))+PI/2; + if (ori1>PI) ori1= ori1-2*PI; + + double ori2= atan2(static_cast(y2-y1),static_cast(x2-x1))+PI/2; + if (ori2>PI) ori2= ori2-2*PI; + + // for all points on the line + LineIterator lit(orientations,Point(x1,y1),Point(x2,y2)); + int i,count=0; + for(i = 0, count=0; i < lit.count; i++, ++lit) { + + float ori= *(reinterpret_cast(*lit)); + + // is line orientation similar to gradient orientation ? + if (min(fabs(ori-ori1),fabs(ori-ori2))(i); + + // set to zero lines of inconsistent orientation + if (consistency < percentage) { + + (*it)[0]=(*it)[1]=(*it)[2]=(*it)[3]=0; + + } + + ++it; + } + + return lines; + } +}; + + +#endif diff --git a/tum_andrive_Andrive.h b/tum_andrive_Andrive.h new file mode 100644 index 0000000..b20d783 --- /dev/null +++ b/tum_andrive_Andrive.h @@ -0,0 +1,24 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class tum_andrive_Andrive */ + +#ifndef _Included_tum_andrive_Andrive +#define _Included_tum_andrive_Andrive +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: tum_andrive_Andrive + * Method: nativeThreshold + * Signature: (JJ)V + */ +JNIEXPORT void JNICALL Java_tum_andrive_Andrive_nativeThreshold + (JNIEnv *, jobject, jlong, jlong); + +JNIEXPORT void JNICALL Java_tum_andrive_Andrive_nativeCannyEdge + (JNIEnv *, jobject, jlong, jlong); + +#ifdef __cplusplus +} +#endif +#endif